如何在 CakePHP 中创建自定义 MySQL 查询?

Posted

技术标签:

【中文标题】如何在 CakePHP 中创建自定义 MySQL 查询?【英文标题】:How to create custom MySQL queries in CakePHP? 【发布时间】:2013-03-02 04:50:05 【问题描述】:

我正在尝试在 Cakephp 中创建自己的 mysql 查询。

这是我的LocationsController.php

<?php
App::uses('Location', 'Model');
class LocationsController extends AppController

    public $helpers = array('html', 'Form');
    function index()
    
        $this->loadModel("Location");
        $this->Location->get();
    

这是我的LocationModel.php

<?php
App::uses('AppModel', 'Model');
class LocationModel extends Model 

    public $name = 'Location';

    public function get()
    
        $this->Location->query("SELECT * FROM locations;");
    

如您所见,我只是想执行一个简单的查询,但它不起作用。我收到此错误:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error 
in your SQL syntax; check the manual that corresponds to your MySQL server 
version for the right syntax to use near 'get' at line 1

当我使用 find("all") 之类的魔法方法之一时,它会起作用...

你能看出问题所在吗?我真的做不到,我只是想做一个简单的任务!

【问题讨论】:

如果你是Location 模型,那不就是$this-&gt;query('SELECT * FROM locations'); 吗? 检查下面的答案,让我知道接下来会发生什么! 当您已经获得位置模型并且可以执行 find(all) 时,我看不出有任何合理的理由在这里使用自定义查询...您应该始终问自己是否真的必须使用自定义查询.然后你会发现你从来没有真正需要它们。 【参考方案1】:

Location 模型的类名应该是Location,而不是LocationModel

因此,CakePHP 将为 Locations 数据库表生成一个“通用”模型,并使用该模型而不是您自己的模型。因为这个泛型模型确实没有get()方法,所以会将get作为SQL语句执行,导致报错

另外,在模型内部,你不应该使用$this-&gt;Location-&gt;query();,而应该使用$this-&gt;query();

【讨论】:

query() 能防止 SQL 注入吗? @FranciscoCorrales not 如果你向它传递一个包含未转义变量的文字查询,但它确实支持准备好的语句(参见源代码@987654321 @)。像这样使用它:$this-&gt;query('SELECT * FROM foo WHERE id=? OR somefield=?', array(123, 'foo'));【参考方案2】:

位置控制器应该是:

<?php
App::uses('Location', 'Model'); // Y do u need this?
class LocationsController extends AppController

    public $helpers = array('Html', 'Form');
    function index()
    
        $this->loadModel("Location");
        $this->LocationModel->getLocations(); // I will strongly discourage using get()
    

位置模型应该是:

<?php
App::uses('AppModel', 'Model');
class LocationModel extends Model 

    public $name = 'Location';

    public function getLocations() // Try to avoid naming a function as get()
    
    /** Choose either of 2 lines below **/

        return $this->query("SELECT * FROM locations;"); // if table name is `locations`
        return $this->query("SELECT * FROM Location;"); // if table name is `Location` since your public name is `Location`
    

【讨论】:

query() 能防止 SQL 注入吗? 不。它没有。但是,您可以使用 is_int()ctype_alnum 等 php 函数来检查变量 好吧,请看看这个,让我知道你的想法:github.com/cakephp/cakephp/blob/2.4.9/lib/Cake/Model/… 2.4.9! prevent SQL injection ,不是吗?另外,您展示的内容将使用 func_get_args 进一步解析。消毒过程会很慢,但不会伤害任何人:)

以上是关于如何在 CakePHP 中创建自定义 MySQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中创建自定义对象?

如何在 Facebook SDK 中创建自定义分享按钮

如何在 WordPress 中创建自定义表单?

如何在 React Native 中创建自定义日历?

如何在 JavaScript 中创建自定义错误?

如何在 QT5.6.1 中创建自定义按钮