Неустранимая ошибка PHP: вызов функции-члена num_rows () для логического значения в - PullRequest
2 голосов
/ 09 мая 2019

Я переместил свой веб-сайт с сервера на другой, и у меня возникла ошибка при попытке перейти на страницу результатов теста. Ошибка говорит:

Не удалось обработать этот запрос.

После просмотра журнала ошибок php я нашел следующую строку:

[09-May-2019 08:19:13 Asia/Kolkata] PHP Fatal error:  Call to a member 
function num_rows() on boolean in
/home/USER/public_html/PATH/PATH/models/Result_model.php on line 
143

Это основная часть содержимого файла, с учетом того, что я прокомментировал приведенную строку 143 как:

function get_result($rid){
$logged_in=$this->session->userdata('logged_in');
$uid=$logged_in['uid'];
if($logged_in['su']=='0'){
$this->db->where('savsoft_result.uid',$uid);
}
$this->db->where('savsoft_result.rid',$rid);
 $this->db->join('savsoft_users','savsoft_users.uid=savsoft_result.uid');
$this->db->join('savsoft_group','savsoft_group.gid=savsoft_users.gid');
$this->db->join('savsoft_quiz','savsoft_quiz.quid=savsoft_result.quid');
$query=$this->db->get('savsoft_result');
return $query->row_array();


}


function last_ten_result($quid){
    $this->db->order_by('percentage_obtained','desc');
    $this->db->limit(10);       
    $this->db->where('savsoft_result.quid',$quid);
    $this->db->join('savsoft_users','savsoft_users.uid=savsoft_result.uid'); 
    $this->db->join('savsoft_quiz','savsoft_quiz.quid=savsoft_result.quid');
    $query=$this->db->get('savsoft_result');
    return $query->result_array();
}



function get_percentile($quid,$uid,$score){
$logged_in =$this->session->userdata('logged_in');
$gid= $logged_in['gid'];
$res=array();
$this->db->where("savsoft_result.quid",$quid);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$query = $this -> db -> get('savsoft_result');
$res[0]=$query -> num_rows();    // THIS IS LINE 143


$this->db->where("savsoft_result.quid",$quid);
$this->db->where("savsoft_result.uid !=",$uid);
$this->db->where("savsoft_result.score_obtained <=",$score);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$querys = $this -> db -> get('savsoft_result');
$res[1]=$querys -> num_rows();

return $res;

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

Кто-нибудь получил решение для этой проблемы?

1 Ответ

0 голосов
/ 09 мая 2019

Как обсуждалось в нашем чате, проблема вызвана миграцией сервера и новым сервером, использующим MySQL 5.7+, который по умолчанию включает only_full_group_by.

Причина в том, что MySQL не может выбрать определитель значения, связанного с группировками, и выдает ошибки вместо того, чтобы молча игнорировать потенциально нежелательные значения в операторе SELECT, как это было в предыдущих версиях MySQL.
Например: SELECT customer, SUM(order_total) FROM orders GROUP BY purchase_date
Если у двух или более клиентов одинаковый purchase_date, может быть показан только один, и MySQL должен определить, какой из них вам нужен.

Поскольку CodeIgniter по умолчанию использует SELECT * для оператора при использовании $this->db->get(), возникает ошибка.

Чтобы решить эту проблему, настоятельно рекомендуется обновить все ваших запросов GROUP BY во всем приложении, чтобы они были совместимы с MySQL 5.7. Это обеспечит получение правильных значений из ваших GROUP BY утверждений.

Есть несколько вариантов, которые вы можете использовать, в порядке наименее сложных и наиболее полезных.

1) Используйте $this->db->count_all_results() вместо $query->num_rows()
(он же: SELECT COUNT(*))

$this->db->where("savsoft_result.quid",$quid);
$this->db->group_by("savsoft_result.uid");
$res[0] = $this->db->count_all_results('savsoft_result');

$this->db->where("savsoft_result.quid",$quid);
$this->db->where("savsoft_result.uid !=",$uid);
$this->db->where("savsoft_result.score_obtained <=",$score);
$this->db->group_by("savsoft_result.uid");
$res[1] = $this->db->count_all_results('savsoft_result');

Обратите внимание на удаление order_by, так как он не нужен для подсчета строк.

2) Ограничить значения только теми, которые сгруппированы

$this->db->select('savsoft_result.uid');
$this->db->where("savsoft_result.quid",$quid);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$query = $this->db->get('savsoft_result');
$res[0] = $query->num_rows();

$this->db->select('savsoft_result.uid');
$this->db->where("savsoft_result.quid",$quid);
$this->db->where("savsoft_result.uid !=",$uid);
$this->db->where("savsoft_result.score_obtained <=",$score);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$querys = $this->db->get('savsoft_result');
$res[1] = $querys->num_rows();

3) Явно определите ANY_VALUE для всех несгруппированных столбцов
(это эквивалент отключения only_full_group_by)

Используя запрос, который я предоставил выше.

SELECT ANY_VALUE(customer), SUM(order_total) FROM orders GROUP BY purchase_date

Так что вы должны иметь возможность использовать что-то вроде следующего, обязательно добавьте ВСЕ не сгруппированные столбцы в связанной таблице.

$this->db->select('ANY_VALUE(savsoft_result.quid), ANY_VALUE(savsoft_result.score_obtained), savsoft_result.uid');
$this->db->where("savsoft_result.quid",$quid);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$query = $this -> db -> get('savsoft_result');
$res[0] = $query->num_rows();

$this->db->select('ANY_VALUE(savsoft_result.quid), ANY_VALUE(savsoft_result.score_obtained), savsoft_result.uid');
$this->db->where("savsoft_result.quid",$quid);
$this->db->where("savsoft_result.uid !=",$uid);
$this->db->where("savsoft_result.score_obtained <=",$score);
$this->db->group_by("savsoft_result.uid");
$this->db->order_by("savsoft_result.score_obtained",'DESC');
$querys = $this->db->get('savsoft_result');
$res[1] = $querys->num_rows();

В качестве альтернативы вы можете отключить only_full_group_by sql_mode.

Вы можете временно отключить его, обновив глобальную переменную, выполнив оператор SET GLOBAL.

SET GLOBAL sql_mode=(SELECT TRIM(BOTH ',' FROM REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')));

Это извлечет используемый в настоящее время sql_mode и удалит часть ONLY_FULL_GROUP_BY, затем удалит все оставшиеся начальные или конечные запятые. Однако после перезапуска службы MySQL вам нужно будет снова выполнить оператор.

Чтобы гарантировать, что only_full_group_by не вернется к включенному при перезапуске службы MySQL, отредактируйте ваш файл конфигурации my.cnf MySQL, чтобы опустить ONLY_FULL_GROUP_BY в объявлении sql_mode.

Вы можете получить текущий sql_mode, выполнив инструкцию

SHOW VARIABLES LIKE 'sql_mode';

Что должно возвращать что-то вроде:

ONLY_FULL_GROUP_BY,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_VALUE_ON_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Скопируйте весь текст, затем объявите sql_mode в файле my.cnf, удалив часть ONLY_FULL_GROUP_BY.

[mysqld]
sql_mode=ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_VALUE_ON_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

После внесения изменений в файл my.cnf перезапустите службу MySQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...