Неустранимая ошибка: вызов функции-члена bind_param () на boolean

Я занят функцией, которая получает настройки из БД, и внезапно я столкнулся с этой ошибкой:

Fatal error: Call to a member function bind_param() on boolean in C:\xampp2\htdocs\application\classes\class.functions.php on line 16 

Обычно это будет означать, что я выбираю материал из самых разных таблиц и прочее. Но в этом случае я не …

Вот функция getSetting :

 public function getSetting($setting) { $query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?'); $query->bind_param('s', $setting); $query->execute(); $query->bind_result($value, $param); $query->store_result(); if ($query->num_rows() > 0) { while ($query->fetch()) { return $value; if ($param === '1') { $this->tpl->createParameter($setting, $value); } } } else { __('invalid.setting.request', $setting); } } 

Переменная $this->db передается через конструктор. В случае необходимости, вот он:

 public function __construct($db, $data, $tpl) { $this->db = $db; $this->tpl = $tpl; $this->data = $data; $this->data->setData('global', 'theme', $this->getSetting('theme')); } 

Кроме того, поскольку я использую базу данных, мое подключение к базе данных:

 class Database { private $data; public function __construct($data) { $this->data = $data; $this->conn = new MySQLi( $this->data->getData('database', 'hostname'), $this->data->getData('database', 'username'), $this->data->getData('database', 'password'), $this->data->getData('database', 'database') ); if ($this->conn->errno) { __('failed.db.connection', $this->conn->errno); } date_default_timezone_set('Europe/Amsterdam'); } 

Я уже тестировал соединение, на 100% уверен, что он работает по назначению. Я устанавливаю вещи соединения DB в файле конфигурации:

 'database' => array( 'hostname' => '127.0.0.1', 'username' => 'root', 'password' => ******, 'database' => 'wscript' ) 

Теперь странно. таблица существует, существует запрошенная настройка, существует БД, но тем не менее эта ошибка не исчезнет. Вот несколько доказательств правильности БД:

IMG

Проблема заключается в следующем:

 $query = $this->db->conn->prepare('SELECT value, param FROM ws_settings WHERE name = ?'); $query->bind_param('s', $setting); 

Метод prepare() может возвращать false и вы должны это проверить. Что касается того, почему он возвращает false , возможно, имена таблиц или столбцов (в предложении SELECT или WHERE ) неверны?

Кроме того, рассмотрите возможность использования чего-то типа $this->db->conn->error_list для проверки ошибок, возникающих при разборе SQL. (Я иногда повторяю фактические строки операторов SQL и вставляю их в phpMyAdmin для тестирования тоже, но там определенно что-то не удается).

Каждый раз, когда вы получаете …

«Неустранимая ошибка: вызов функции-члена bind_param () в boolean»

… вероятно, потому что есть проблема с вашим запросом. Команда prepare() может возвращать FALSE (логическое), но это общее сообщение об отказе не оставляет вас в стороне от подсказок. Как вы узнаете, что не так с вашим запросом? Вы спрашиваете !

Прежде всего, убедитесь, что отчет об ошибках включен и виден: добавьте эти две строки в начало файла (ов) сразу после открытия <?php :

 error_reporting(E_ALL); ini_set('display_errors', 1); 

Если ваш отчет об ошибках установлен в php.ini, вам не придется беспокоиться об этом. Просто убедитесь, что вы обрабатываете ошибки изящно и никогда не раскрываете истинные причины каких-либо проблем для ваших пользователей. Выявление истинной причины для общественности может быть приглашением на золото с гравировкой для тех, кто хочет нанести вред вашим сайтам и серверам. Если вы не хотите отправлять ошибки в браузер, вы всегда можете следить за журналами ошибок веб-сервера. Расположение журналов будет отличаться от сервера к серверу, например, в Ubuntu журнал ошибок обычно находится в /var/log/apache2/error.log . Если вы изучаете журналы ошибок в среде Linux, вы можете использовать tail -f /path/to/log в окне консоли, чтобы видеть ошибки, которые происходят в режиме реального времени …. или по мере их создания.

После того, как вы отделитесь от стандартной отчетности об ошибках, добавив проверку ошибок в вашем соединении с базой данных и запросах, вы получите гораздо больше информации о проблемах. Посмотрите на этот пример, где имя столбца неверно. Во-первых, код, который возвращает генерическое сообщение об ошибке:

 $sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?"; $query = $mysqli->prepare($sql)); // assuming $mysqli is the connection $query->bind_param('s', $definition); $query->execute(); 

Ошибка является общей и не очень полезной для вас в решении того, что происходит.

С еще несколькими строками кода вы можете получить очень подробную информацию, которую вы можете использовать для немедленного решения проблемы. Проверьте инструкцию prepare() для правдивости, и если это хорошо, вы можете перейти к привязке и исполнению.

 $sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?"; if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection $query->bind_param('s', $definition); $query->execute(); // any additional code you need would go here. } else { $error = $mysqli->errno . ' ' . $mysqli->error; echo $error; // 1054 Unknown column 'foo' in 'field list' } 

Если что-то не так, вы можете выплюнуть сообщение об ошибке, которое приведет вас к проблеме. В этом случае в таблице нет столбца foo , решение проблемы тривиально.

Если вы выберете, вы можете включить эту проверку в функцию или класс и расширить ее, обработав ошибки изящно, как упоминалось ранее.

prepare return boolean только тогда, когда он не сработает, поэтому FALSE , чтобы избежать ошибки, вам нужно проверить, является ли это True сначала перед выполнением:

 $sql = 'SELECT value, param FROM ws_settings WHERE name = ?'; if($query = $this->db->conn->prepare($sql)){ $query->bind_param('s', $setting); $query->execute(); //rest of code here }else{ //error !! don't go further var_dump($this->db->error); } 

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

 $statement->close(); 

Если синтаксис верен, следующий запрос тоже будет работать.

Другой ситуацией, которая может вызвать эту проблему, является неправильное кастинг в ваших запросах.

Я знаю, это может показаться очевидным, но я столкнулся с этим, используя tablename вместо Tablename . Проверьте свои запросы и убедитесь, что вы используете тот же случай, что и фактические имена столбцов в таблице.