使用 AJAX 和 CakePHP 保存数据
Posted
技术标签:
【中文标题】使用 AJAX 和 CakePHP 保存数据【英文标题】:Save data using AJAX and CakePHP 【发布时间】:2011-09-11 05:12:18 【问题描述】:我今天花了很多时间研究如何在 cakephp 中使用 ajax 请求来保存数据,现在我知道了,cakephp 网站上的文档似乎有点缺乏这个特定主题。
我有几个可排序的列表,我需要在排序时保存每个列表项的位置。我有一个 ajax 请求设置如下,在移动项目时触发:
$.ajax(
url: "/orders/save_column_order",
type:"POST",
data:"data="+data
);
控制器中引用的函数是:
function save_column_order()
if($this->RequestHandler->isAjax())
SAVE STUFF...
我已经设置了助手等:
var $helpers = array('html','Form','Js');
var $components = array('Session','Email','RequestHandler');
而且它不工作......
所以我的问题是:
1) 向控制器中的操作发送 ajax 请求的当前 url 是什么?是简单的 /controller/action 吗?
2) 我还需要对控制器做什么才能访问 ajax 数据?
奖金:
3) 有没有办法在 CakePHP 框架中包含一个引用数据库设置的自定义 php 文件,以便我可以手动更新我的 mysql 数据库?
【问题讨论】:
【参考方案1】:你们很亲密。
1.) URL 就是 /controller/action。数据在 $this->data 中传递,并且神奇地在操作中可用。 **由于您在帮助程序中列出了“Js”而不是“javascript”,我假设您使用的是 Cake 1.3.x 和 jQuery,因为 jQuery 是 Cake 1.3 的默认值,而 Js 取代了 Javascript/Ajax。
-- 修复你的助手:
var $helpers = array('Html', 'Form', 'Js'=>array("Jquery"));
-- 修复你的 jQuery:
$.ajax(
url:'/orders/save_column_order',
type:'POST',
data:data
);
2.) 使用 Cake 的魔法:
function save_column_order()
if ($this->data != null)
$this->Model->save($this->data);
// whatever else needs doing...
-- 因为你在做 ajax,你可能不想要 Cake 的默认视图渲染行为(只是一个猜测。)如果你想渲染任何视图,它可能只是一个 ajax 回调的标记片段, 所以你可能想把它放在一个元素中而不是一个完整的视图中:
function save_column_order()
// ...
/* arg 1 - you can specify any view or element you like.
arg 2 - enforces your preferred request handling and layout */
$this->set(compact('vars', 'for', 'view'));
$this->render('/elements/new_column_order', 'ajax');
-- 否则,只是抑制渲染:
function save_column_order()
...
$this->autoRender = false;
-- 如果您的保存不起作用,请确保 $this->data 的结构对 Cake-save 友好。如果您需要查看 $this->data 的内容,Cake 的内置调试(从您应用程序的任何位置)将帮助您理顺:
debug($this->data);
3.) 等等,什么?
不确定我是否正确理解您的问题,所以如果这不能涵盖您的问题,请说明您要做什么?
如果您的意思是,Cake 是否允许您手动更新表中的记录,是吗?虽然我不确定你为什么想要。 Cake 极其强大的内置 ORM 是框架的一半,它极其全面的魔力是另一半。
您可以使用 Model::sql() 方法直接写出 SQL,尽管不鼓励这样做,因为它不是非常 OOP 或可重用。
当您在模型中定义关联时,您可以将外键设置为 false 并指定像 Cake 的自动连接中的嵌套选择一样工作的条件。
如果你需要强制 join/s,Cake 的 $options['joins'] 给你完全精细的控制;如果默认的 LEFT 不足以满足您的需要,您可以指定任何类型的 JOIN。
您可以使用 $this->Model->bind() / unbind() 即时创建和中断模型绑定。您可以指定递归级别、应用可包含行为、指定要选择的字段和所有条件。
如果您需要一个子查询,而 Cake 无法正确处理,则 $dbo->buildStatement() 将构建您的 SQL 语句,而 $dbo->expression() 将触发它:
function intricate()
$dbo = $this->Rate->Status->getDataSource();
$subquery = $dbo->buildStatement(
array(
'fields' => array('`Status`.`id`'),
'table' => $dbo->fullTableName($this->Rate->Status),
'alias' => 'Status',
'limit' => null,
'offset' => null,
'joins' => array(),
'conditions' => $subqueryConditions,
'order' => null,
'group' => null
),
$this->Rate->Status
);
$subquery = "Status.id = (".$subquery.")";
$status = $dbo->expression($subquery);
$options['fields']=
array(
"Rate.id", "Rate.plan_id", "Rate.status_id","Rate.rate", "Plan.id",
"Plan.company_id", "Plan.name", "Company.id", "Company.name"
);
$options['conditions']=
array(
$status,
"Geographical.name LIKE '%$this->zip%'"
);
$rates = $this->Rate->find('all', $options);
$this->set(compact('rates'));
——如果你的意思是——Cake 是否允许你即时交换数据库配置,是的。但是,这样做可能会变得非常顽固,尤其是当 Cake 的魔法是其中的一部分时。
您可以在 /app/config/database.php 中添加多个数据库配置 -
class DATABASE_CONFIG
var $default = array(
'driver' => 'mysql',
'persistent' => false,
'host'=>'localhost',
'login' => 'cake',
'password' => 'icing',
'database' => 'dev'
);
var $offsite = array(
'driver' => 'mysql',
'persistent' => false,
'host' => '11.22.33.44', // or whatever
'login' => 'cake',
'password' => 'frosting',
'database' => 'live'
);
-- 根据您的情况的复杂性,在您的控制器/模型中切换它们会变得有点紧张:
// Model::getDataSource()->configKeyName holds whichever db config you're using
if ($this->Model->getDataSource()->configKeyName != 'default')
// do something, for example, change models, tables, reload schema, etc.
$this->loadModel('Special')
$this->Model->table = 'extras';
$this->Model->schema(true);
else
// predictably, Model::setDataSource($configKey) changes configs
$this->Model->setDataSource('offsite');
-- 如果这是你的意思,我可以粘贴我几周前写的一段代码,要求我将 ajax 表单提交(在表单完成的 2 个阶段)保存到 2 个数据库中的 3 个表(一个为我的Cake 应用程序,另一个服务于旧版 CodeIgniter 应用程序)展示了所有这些花哨的步法以及一些很好的老式 Cake 魔术连接保存/更新快捷方式。 (我还必须生成选择性电子邮件,最后,触发一个 REST 请求,将新插入的记录的 id/s 传递给 CI 应用程序以触发它的处理。哇!)
无论如何,HTH。 :)
【讨论】:
非常感谢您的帮助!我已经进行了您所说的更改,但是我现在从 ajax 请求中收到了 404 错误。多亏了你,我离让它工作更近了,知道 404 可能是什么吗?回覆。 3)你绝对正确,它不是很蛋糕,我完全忘记了自定义 sql 语句 - 我认为自定义 sql 是我做错了什么的标志,现在我不需要使用它!还有你的权利,我正在使用 JQuery 和 cake 1.3。 Np。错误 404 通常表示某些东西已关闭 - 可能是权限,还是路由错误?否则 Cake 会抛出 Missing Controller / Action / View / 不管什么。每当 Cake 发出 404 错误时,我都会直接查看我的错误日志——首先是 Cake 的,然后是 Apache 的——看看它试图提取什么。检查所有权/权限,查找文件/类名中的拼写错误,所有这些小东西。如果您使用的是 Auth,请将您的 ajax 控制器操作添加到您的允许列表中。 Cake 的 debug() 是救命稻草,在调试 cake ajax 问题方面,没有什么比 FirePHP(与 Cake 集成)更好的了。 你是救生员和英雄!我有一个愚蠢的 url 问题,给了我 404。非常感谢。【参考方案2】:-
是的,就这么简单。
-
要访问您发送的数据,您可以像往常一样使用
$this->data
访问数据
为什么不使用phpmyadmin 之类的工具?
【讨论】:
phpMyAdmin 是一场安全噩梦。完全不适合生产服务器。 IME,团队开发服务器的最后选择/临时解决方案。 此外,直接访问 db manip 解决方案实际上只适合开发人员类型的用户。 在无限的现实场景中,应用程序必须解决复杂/奇异的数据库和数据源设置和操作的需求。我的项目-> 完美示例:当前的逐步淘汰/迁移阶段意味着同时处理 Cake 和 CI 的数据库。 2 个框架、2 个数据库/服务器(表略有不匹配!)、3 个模型、白名单、重新加载模式等......【参考方案3】: public function add_project()
$this->autoRender = false;
$this->layout = 'ajax';
if ($this->RequestHandler->isAjax())
$this->Project->set($this->request->data);
$this->request->data['Project']['user_id'] = $this->Session->read('Auth.User.id');
$this->request->data['Project']['created_by'] = $this->Session->read('Auth.User.id');
$this->request->data['Project']['updated_by'] = $this->Session->read('Auth.User.id');
//$this->request->data['Skill']['accept_decline'] = 0;
$this->User->set($this->request->data['Project']);
Configure::write('debug', 0);
if ($this->Project->validates(array('fieldList' => array('project_title', 'show_on', 'summary'))))
if ($this->Project->save($this->request->data, false))
$response['status'] = 'succses';
$response['message'] = 'data sent';
echo json_encode($response);
exit();
else
$response['status'] = 'error';
$response['model'] = 'Project';
$response['message'] = 'data not sent';
echo json_encode($response);
exit();
else
$response['status'] = 'invalid';
$response['model'] = 'Project';
$errors = $this->Project->validationErrors;
$response['errors'] = $errors;
echo json_encode($response);
exit();
【讨论】:
以上是关于使用 AJAX 和 CakePHP 保存数据的主要内容,如果未能解决你的问题,请参考以下文章
cakephp 在不使用视图的情况下保存 HABTM 关系的数据
使用 Cakephp model::save() 将数据保存到不同的数据库表