Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何为分页器排序顺序使用函数表达式?_Php_Mysql_Cakephp_Pagination_Cakephp 3.0 - Fatal编程技术网

Php 如何为分页器排序顺序使用函数表达式?

Php 如何为分页器排序顺序使用函数表达式?,php,mysql,cakephp,pagination,cakephp-3.0,Php,Mysql,Cakephp,Pagination,Cakephp 3.0,在对数据库中的ip地址进行排序时,我使用MySQL提供的INET_ATON函数 现在,当我试图在CakePHP3中实现这一点时(我是新手),我失败了 以下是我得到的: class Ip extends Entity { /** * Fields that can be mass assigned using newEntity() or patchEntity(). * * Note that when '*' is set to true, this a

在对数据库中的ip地址进行排序时,我使用MySQL提供的INET_ATON函数

现在,当我试图在CakePHP3中实现这一点时(我是新手),我失败了

以下是我得到的:

class Ip extends Entity
{

    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array
     */
    protected $_accessible = [
        '*' => true,
        'id' => false,
    ];

    protected $_virtual = ['ip_address'];

    protected function _getIpAddress()
    {
        $vc = (new FunctionsBuilder())->inet_aton(['ip' => 'literal']);
        return $vc;
    }
}
这是我的控制器方法

<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\ORM\TableRegistry;
use Cake\Validation\Validator;
use Cake\Database\FunctionsBuilder;
/**
 * Ips Controller
 *
 * @property \App\Model\Table\IpsTable $Ips
 */
class IpsController extends AppController
{

    /**
     * Index method
     *
     * @return void
     */
    public function index()
    {
        $this->paginate = [
            'contain' => ['Users'],
            'order' => [(new FunctionsBuilder())->inet_aton(['ip' => 'literal'])]
        ];
        $this->set('ips', $this->paginate($this->Ips));
        $this->set('_serialize', ['ips']);
    }
改用附加列
就我个人而言,我会将IP的整数表示另外存储在一个单独的列中,并使用该列进行排序。由于DBMS可以使用索引,这不仅可以为您提供更好的性能,还可以避免处理函数表达式所需的额外逻辑,并让您像往常一样使用分页组件

在视图中,只需使用新列的名称,并手动定义要为排序链接显示的名称,如

<?= $this->Paginator->sort('ip_int', 'IP') ?>
或者使用自定义查询,如

$query = $this->Ips->find();
$query->orderAsc($query->func()->inet_aton(['ip' => 'literal']));

$this->set('ips', $this->paginate($query));
您必须使用一点自定义逻辑才能使其与视图一起工作,因为分页辅助程序设计为仅处理列名(字符串)

具有视图辅助对象的动态排序 现在,如果还想使用分页视图帮助器,则必须创建一些逻辑来计算帮助器生成的排序列和方向,并手动配置选项/查询,类似于上面的示例

下面是一个基本示例,使用
Query::orderAsc()
Query::orderDesc()
方法可以在使用函数表达式时定义方向(表达式不能通过
Query::order()
与其他值组合)

这应该主要是自我解释,首先检查分页器助手生成的
排序
键是否已传递,如果未传递,或者是,并且是您的IP列,请针对可能设置的
方向
键应用自定义顺序。如果
sort
不是您的IP列,只需忽略它,分页器将拾取值并像往常一样计算和使用它们

类似地,您可以在手动创建
orderClauseeExpression
实例时设置方向,但我个人可能会坚持使用自定义查询和函数生成器

再干一点? 如果您想让它更具可重用性,您可能需要研究自定义/扩展分页器组件、自定义查找器和行为

实体是数据容器 最后但并非最不重要的一点是,您的实体与所有这些无关,它只是一个数据容器,所以抛开虚拟财产,它们无论如何都不能用于查找

另见

您想对数据进行排序吗?杰普,我想对ip地址进行排序,使1.1.1.18不会出现在1.1.1.2之前。您可以添加控制器/索引方法吗?还要添加您现在的输出以及您希望看到的实际内容?您希望将ip视为描述顺序吗?还是作为ip模式?非常好的解释!我抛弃了虚拟财产,选择了查看助手的方法!尽管使用整数表示的额外列可能是最简单的方法。
$query = $this->Ips->find();
$query->orderAsc($query->func()->inet_aton(['ip' => 'literal']));

$this->set('ips', $this->paginate($query));
$query = $this->Ips->find();

$sort = $this->request->query('sort');
if ($sort === null || $sort === 'ip') {
    $method = 'orderAsc';
    if ($this->request->query('direction') === 'desc') {
        $method = 'orderDesc';
    }
    $query->{$method}($query->func()->inet_aton(['ip' => 'literal']));
}

$this->set('articles', $this->paginate($query));