CakePHP的Model::afterFind()回调如下:
afterFind(array $results, boolean $primary = false)
Run Code Online (Sandbox Code Playgroud)
根据文件:
该
$primary参数指示当前模型是否是查询源自的模型,或者是否将该模型作为关联查询.如果将模型作为关联查询,则格式$results可以不同.
它们可以有所不同,但实验表明它们并不总是不同.据我所知,$primary参数实际上并没有那么有用.如果它设置为false你可能会或可能不会得到一个扁平的数据结构,所以你可能会或可能不会结束可怕的"不能使用字符串偏移作为数组"错误消息.
虽然我还没有尝试过,但基于文档的想法是$primary完全忽略该标志并只检查数据:
public function afterFind($results, $primary = false) {
if (array_key_exists(0, $results) {
// operate on $results[0]['User']['fieldname']
} else {
// operate on $results['fieldname']
}
return $results;
}
Run Code Online (Sandbox Code Playgroud)
这是hackish,我不喜欢它,但它似乎更有用$primary.
明确说明,我的问题是:
$primary标志实际上有用吗?$results,或者我错过了什么?我曾经使用CakePHP 1.3,但这是我第一次涉及CakePHP 2.0和PHP异常,所以如果我的问题看起来很罗嗦,请耐心等待.
在我AppController的beforeFilter()设置中,我设置了几个变量,$this->set()以便在我的视图模板中使用.
在我的UsersController代码中看起来大致如下:
public function beforeFilter() {
parent::beforeFilter();
if (userDeniedAccess()) {
throw new ForbiddenException();
}
}
Run Code Online (Sandbox Code Playgroud)
假设函数userDeniedAccess()封装了我的授权检查.
这一切都很好,我期待它时会收到403错误.但是,抛出异常时,AppController::beforeFilter()不再设置已设置的视图变量,从而导致视图模板出错.如果未抛出异常,则会正确设置变量.
如果必须的话,我可以编写缺失的变量,但我真的想知道导致这种行为的原因.我UsersController和他的CakeErrorController延伸AppController.当然,我希望当抛出异常并CakeErrorController实例化时,它会为我生成相同的视图变量.
但是,似乎永远不会Controller::startupProcess()调用该方法(包括调用beforeFilter())CakeErrorController.据我所知,这是由调度员对常规请求完成的,但错误控制器的生命周期是不同的.
我在CakePHP 1.3中看到了类似行为的描述(如此),但当然CakePHP的错误处理代码已经在2.0中彻底改变了.
所以要么:
我知道你对案例3无能为力,但如果前两个中的任何一个适用,我会感谢那些比我更了解的人的意见.
谢谢!
编辑:设置视图变量beforeRender()确实解决了我的问题.但是,我仍然想知道是否故意beforeFilter()永远不会被召唤CakeErrorController.
以前我依靠递归,但我没有得到一些解决方案,然后我发现Containable适用于这些.
我正在开发一个电影评论网站.在那里,我需要显示与特定类型相关的电影列表.
我有以下代码:
//example
$genre = "drama";
$options = array(
'contain' => array(
'Movie',
'MoveiGenre.Genre' => array(
'conditions' => array('MovieGenre.Genre.name = "'.$genre.'"')
),
'MovieGenre.Genre.name'
),
'recursive' => 2,
'limit' => 10
);
$this->paginate = $options;
$this->set('movies',$this->paginate());
Run Code Online (Sandbox Code Playgroud)
真正的问题从这里开始,我得到所有的电影,即使它与流派"戏剧"无关.我哪里错了?
让我解释一下数据库表:
表:电影
----------------------------
| id | title | description |
----------------------------
| 1 | mov1 | something1 |
| 2 | mov2 | something2 |
| 3 | mov3 | something3 |
----------------------------
Run Code Online (Sandbox Code Playgroud)
表:流派
---------------
| id | name |
---------------
| 1 …Run Code Online (Sandbox Code Playgroud) recursion cakephp conditional-statements containable cakephp-2.0
我正在编写一个bash脚本来定期将数据传输到远程系统.我有一个生成流的本地命令,以及一个使用它的远程命令,所以我做的是这样的:
generate_data | ssh remoteserver.example.com consume_data
Run Code Online (Sandbox Code Playgroud)
(我设置了ssh键,所以我可以非交互式地执行此操作.)这很好用.但是,由于这将是一个自动化过程(作为一个cron作业运行),有时可能会在有限的带宽上传输大量数据,我希望能够在我的日志文件中定期进行更新.我曾经想过使用pv(管道查看器),这是我能想到的最好的:
generate_data | pv -fb | ssh remoteserver.example.com consume_data
Run Code Online (Sandbox Code Playgroud)
再次,它的工作原理...... 但是 pv真的是用终端输出编写的,所以我最终在日志中看起来很乱
2.06MB^M2.19MB^M2.37MB^M 2.5MB^M2.62MB^M2.87MB^M3MB^M3.12MB^M3.37MB
Run Code Online (Sandbox Code Playgroud)
我更喜欢日志消息
<timestamp> 2.04MB transferred...
<timestamp> 3.08MB transferred...
Run Code Online (Sandbox Code Playgroud)
如果有人对如何做到这一点有任何聪明的想法,或者通过不同的论点pv或通过其他机制,我将不胜感激.
编辑:感谢您的答案到目前为止.当然,有很多可能的家庭酿造解决方案; 我希望找到一些可以"开箱即用"的东西.(并不是说我排除了自酿;最终可能是最简单的事情.既然pv已经完成了我所需要的98%,我宁愿不重新发明它.)
PostScript:这是我最终使用的那条线,希望它可能在某些时候帮助别人.
{ generate_data | pv -fbt -i 60 2>&3 | ssh remoteserver consume_data } 3>&1 | awk -vRS='\r' '{print $1 " transferred in " $2; fflush();}' >> logfile
Run Code Online (Sandbox Code Playgroud) 我有这样的模型关系:
Project的hasMany SubProject的hasManyItem
我想设置一个containable数组,以便我可以找到Item属于某个特定的所有s Project,并对结果进行分页.所以,在我的ItemsController身上:
public $paginate = array(
'Item' => array(
'limit' => 10,
'order' => array('
'Item.create_time' => 'desc'
),
'contain' => array(
'SubProject' => array(
'Project'
)
)
)
);
Run Code Online (Sandbox Code Playgroud)
在某个地方,显然,我需要设置一个类似的条件"SubProject.project_id = $pid",但我尝试过的任何事情都不会产生正确的结果.我能管理的最好的结果是这样的:
Array
(
[0] => Array
(
[Item] => Array
(
[id] => 13
[file_name] => foo.tar.gz
.... other keys ...
[create_time] => 2013-01-23 14:59:49
[subProject_id] => 4
)
[SubProject] => Array
( …Run Code Online (Sandbox Code Playgroud) 使用CakePHP的表单助手生成一个复选框很容易; 使用文档中的示例:
echo $this->Form->checkbox('done',array('value' => 555));
Run Code Online (Sandbox Code Playgroud)
这将生成以下HTML:
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />
Run Code Online (Sandbox Code Playgroud)
这一切都很好,隐藏字段用于强制提交"完成"字段的值,即使该框仍未选中.
现在,为了论证,让我们说这个字段的数据库定义是ENUM('yes','no').当然,我可以轻松地将复选框的值更改为"是".但是,如果未选中,则从隐藏元素提交值"0".这不会从mysql产生错误或警告,因为0始终是枚举字段的合法值; 它看起来像一个空字符串.
我可以更改CakePHP生成的隐藏字段的值("否"),还是我需要抑制自动生成并自己创建隐藏字段?(随着复选框的数量而增长的烦恼.)
我相信这一切都适用于单选按钮组 - 至少如果它们没有默认选择.
我正在使用CakePHP 1.3.谢谢.
cakephp ×5
cakephp-2.0 ×2
bash ×1
cakephp-1.3 ×1
containable ×1
recursion ×1
scripting ×1
unix ×1