2016-02-29 4 views
1

У меня есть следующий код в CakePHP.Числовая сортировка в CakePHP paginator

<th> <?php echo $this->Paginator->sort('standard_id', 'Standard'); ?></th> 
<th> <?php echo $this->Paginator->sort('id'); ?> </th> 
<th> <?php echo $this->Paginator->sort('title'); ?> </th> 

Мои данные standard_id, как это:

  • 3-
  • 4-
  • 10th
  • ... и т.д.

Мои пробл em is standard_id не отсортировано должным образом, оно рассматривает его как строку. Я хочу применить числовую сортировку.

Любая идея?

+1

Я предполагаю, что ваши данные представляют собой сочетание числа и символа, поэтому он будет рассматривать только как строку. Можете ли вы указать, какую версию CakePHp вы используете? –

+0

Я использую cakephp-2.4.7 –

+0

По моим сведениям, сортировка по умолчанию дает приведенный выше результат. В PHP существует возможность изменить поведение сортировки по умолчанию для буквенно-цифровых строк с помощью natsort(), т.е. Natural sort. http://php.net/manual/en/function.natsort.php. Поскольку сортировка CakePHP применяется к запросу MYSQL, вы можете попробовать другой вариант. Пожалуйста, прочитайте, как Natural Sort реализована для CakePHP и MYSQL. http://gobagel.blogspot.in/2010/10/cakephp-12-natural-alphanumeric-sorts.html –

ответ

1

Добавьте следующие модели:

public function __construct($id = false, $table = null, $ds = null) { 
    parent::__construct($id, $table, $ds); 
    $this->virtualFields['standard_id_numeric'] = sprintf('CAST(%s.standard_id as UNSIGNED)', $this->alias); 
} 

Теперь вы должны иметь возможность сортировать standard_id_numeric.

В качестве альтернативы, вы можете объявить виртуальное поле как:

public $virtualFields = array(
    'standard_id_numeric' => 'CAST(Standard.standard_id as UNSIGNED)' 
); 

Однако, это вызовет ошибку, если создать экземпляр модели с псевдонимом.

См

+0

Он также работает. Но из обоих решений, которые должны быть применимы? У меня есть и другие модули, подобные этому (одно и то же поле standard_id_numeric), и я хочу сделать его общим. поэтому, я помещаю это в AppModel, но он не работает. –

+0

В CakePHP 2.x использование виртуальных полей - правильный подход. Хотя ваше решение может работать и сейчас, довольно хакерское, и в какой-то момент оно наверняка сломает ваше приложение. Что касается ввода этого кода в ваш «AppModel», он должен работать, если вызывается родительский конструктор. Какую ошибку вы получаете? –

+0

дает синтаксическую ошибку. Я думаю, что я делаю что-то неправильно. не знают о концепции виртуального поля. в моем файле индексного файла выглядит так: ' Paginator-> sort ('Standard.standard', 'Standard'); ?> Код программы AppModel выглядит следующим образом: 'public function __construct ($ id = false, $ table = null, $ ds = null) { parent :: __ construct ($ id, $ table, $ ds); $ this-> virtualFields ['standard'] = sprintf ('CAST (Standard.standard as UNSIGNED)', $ this-> alias); } ' –

0

Запрос для естественной сортировки в mysql: SELECT имя_столбца FROM имя_таблицы ORDER BY CAST (имя_колонки AS UNSIGNED) ASC;

Таким образом, я использовал метод обратного вызова «beforeFind» в модели. Код выглядит следующим образом.

public function beforeFind($queryData) { 
    if(isset($queryData['sort'])){ 
     if($queryData['sort'] == "standard" && $queryData['direction']=="asc"){ 
      $queryData['order'][0] = array("CAST(Standard.standard AS UNSIGNED)" => "ASC"); 
     }elseif($queryData['sort'] == "standard" && $queryData['direction']=="desc"){ 
      $queryData['order'][0] = array("CAST(Standard.standard AS UNSIGNED)" => "DESC"); 
     } 
    } 

    return $queryData; 
} 
+0

Не забывайте, что это сделает MySQL невозможным использовать индексы, в результате чего каждая проверяемая строка и, таким образом, замедлит ваш запрос. Я по-прежнему рекомендую хранить необработанные числа или использовать дополнительный столбец для сортировки. – ndm

 Смежные вопросы

  • Нет связанных вопросов^_^