#php #class #pdo #undefined
#php #класс #pdo #неопределенный
Вопрос:
Я относительно новичок в PHP PDO и наткнулся на эту ошибку, когда создавал функцию поиска для всех стран, содержащих указанную строку, и обновляется при каждом вводе ключа с помощью Ajax.
Теперь моя ошибка:
Неустранимая ошибка: вызов неопределенного метода DatabaseHandler::prepare() в E:Program fileswampwwwAjaxsearch.php в строке 27
Search.PHP
<?php
class SearchEngine{
private $html;
public function __construct($conn){
$this->html = '';
$this->html .= '<li class="result">';
$this->html .= '<a target="_blank" href="urlString">';
$this->html .= '<h3>nameString</h3>';
$this->html .= '</a>';
$this->html .= '</li>';
if (isset($_POST["query"])) {
$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_POST['query']);
}
else{
$this->html .= 'Something went wrong';
$search_string = 'a';
}
if (strlen($search_string) >= 1 amp;amp; $search_string !== ' ') {
$query = 'SELECT * FROM country WHERE name LIKE "%' . $search_string . '%"';
$result = $conn->prepare($query);
$result->execute();
$result_array = $result->fetchAll();
foreach ($result_array as $result) {
$display_name = preg_replace("/".$search_string."/i", "<b class='highlight'>".$search_string."</b>", $result['name']);
$display_url = ''.urlencode($result['name']).'amp;lang=en';
$output = str_replace('nameString', $display_name, $html);
$output = str_replace('urlString', $display_url, $output);
echo($output);
}
}
}
} ?>
и мой обработчик базы данных
<?php
class DatabaseHandler
{
public $conn;
public function openConnection($host, $user, $password, $database){
$this->conn = new PDO('mysql:host=localhost;dbname=ajax;charset=utf8', 'root', '');
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
} ?>
Все это вызывается из index.PHP
<?php
require_once("cgi_bin/connection.php");
require_once("Database_Handler.Class.php");
require_once("HTML_Page.Class.php");
require_once("search.php");
$hostname_conn = "localhost";
$database_conn = "ajax";
$username_conn = "root";
$password_conn = "";
$conn = new DatabaseHandler($hostname_conn, $username_conn, $password_conn, $database_conn);
$IndexPage = new page();
$SearchEngine = new SearchEngine($conn);
echo $IndexPage->render(); ?>
Теперь я обнаружил, что вы не можете вызвать функцию ::prepare внутри класса. Но как это исправить?
Несколько замечаний: да, мой код нуждается в некоторой доработке, но я предпочитаю, чтобы он сначала работал, любые предложения очень приветствуются. и $_POST[‘query’]; по какой-то причине всегда не задан, поэтому я пока задаю для запроса значение ‘a’, но это ошибка, которую я могу найти / исправить позже сам.
Любая помощь / комментарий и т.д. очень приветствуются. Спасибо
Комментарии:
1. Пожалуйста, рассмотрите builder как лучший скрипт. То, как вы пытаетесь сделать то, что вам нужно, ужасно.
2. Вы просите меня создать лучший скрипт, хотя это, конечно, лучшее, что я мог из него сделать?
3. Нет. Это не является, по любому определению слова «лучший», лучшим из всего. Кроме лучшей ошибки. Я не пытаюсь вас оскорбить, просто чтобы мотивировать вас, чтобы вы могли сделать больше (потому что вы можете)
Ответ №1:
Вы написали:
$conn = new DatabaseHandler($hostname_conn, $username_conn, $password_conn, $database_conn);
Как если бы конструктор возвращал соединение
Это должно быть
$db = new DatabaseHandler();
$conn = $db->openConnection($hostname_conn, $username_conn, $password_conn, $database_conn);
Комментарии:
1. Спасибо, это сработало для меня. И я понимаю, почему это не сработало и почему это работает сейчас. Спасибо, что помогли мне!
2. @krijin еще одна вещь обрабатывайте эти параметры из класса db, который вы не хотите передавать извне
3. Это НИКОГДА НЕ будет работать без моей модификации для возврата свойства $conn . openConnection не имеет возвращаемого значения в исходном скрипте. Это не должно быть ответом.
4. @edwardmp Да. Конструктор должен вернуть объект PDO.
5. @edwardmp Это предложение работает для меня, или это неаккуратное решение, а не «безопасный код»?
Ответ №2:
$conn
это не объект PDO, это объект DatabaseHandler
, у которого нет имени какого-либо метода prepare
. Следовательно, вы вызываете prepare не для того класса.
Просто вызовите метод openConnection(), который возвращает экземпляр PDO, и назначьте его.
// use it like this
$db = new DatabaseHandler();
$conn = $db->openConnection($hostname_conn, $username_conn, $password_conn, $database_conn);
<?php
class DatabaseHandler
{
public $conn;
public function openConnection($host, $user, $password, $database){
$this->conn = new PDO('mysql:host=localhost;dbname=ajax;charset=utf8', 'root', '');
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// return the PDO instance
return $this->conn;
}
}
?>
В этом случае возвращается экземпляр PDO, который должен иметь имена методов prepare
и, следовательно, будет работать.
Комментарии:
1.Я не думаю, что это не сработает. Поправьте меня, если я ошибаюсь, но
__construct
всегда возвращает новый экземпляр текущего класса.2. Я посмотрел, вы правы. Таким образом, обходным путем было бы просто использовать метод openConnection напрямую. Отредактирует сообщение.
3. Я думаю, что @NiettheDarkAbsol прав, и если нет, могу ли я получить еще несколько инструкций, я не совсем понимаю, как это исправить. Но спасибо, что помогли мне!
4. Когда вы создаете экземпляр класса (с помощью new ), вы вызываете конструктор классов, который всегда возвращает экземпляр класса, который вы только что создали. Вам нужен экземпляр объекта PDO.
5. Кажется, никто до сих пор не предполагает, что оригинальный сценарий OP нарушает практически каждое преобразование ООП, когда-либо написанное.