Ребята, здравствуйте. Пытаюсь переписать процедурный код, в ООП. Столкнулся с проблемой экранирования функцией mysqli_real_escape_string. Хотя и есть сомнения что дело не в ней. Помогите разобраться пожалуйста. Код прилагаю. Код (Text): <?php include "Database.php"; // Подключение класса БД $db = new Database($dbhost, $dbuser, $dbpass, $dbname); /******************************** Проверка при регистрации ****************************************** */ if(isset($_POST["newAccUserEmail"])){ // Если существует запрос в переменной пост которая приходит из юнити $email = $db->real_escape_string($_POST["newAccUserEmail"]); $password = $db->real_escape_string($_POST["newAccPassword"]); // Проверяем чтобы поля не были пустыми if($email != "" && $password != ""){ $account = $db->query('SELECT * FROM accounts WHERE email = ?', $email)->fetchArray(); if ($account['email'] == 0) { $db->query('INSERT INTO accounts (email, password) VALUES (?,?)', $email, $password); echo "Регистрация: email " . $email . " and password: " . $password; // Текст который выводится в public Text info; }else{ echo "Этот email уже зарегистрирован."; } }else{ echo "Оба поля обязательны. Введите свой email и придумайте пароль."; } } /**********************************************************************************************************/ Вот такой код я написал. В ООП из процедурного. Вот что выдаёт консоль при отправке данных в БД в юнити Код (Text): успешное подключение<br /> Fatal error: Uncaught Error: Call to undefined method Database::real_escape_string() in C:\OpenServer\domains\hstest.loc\index.php:49 Stack trace: #0 {main} thrown in C:\OpenServer\domains\hstest.loc\index.php on line 49<br /> 49 строка это: $email = $db->real_escape_string($_POST["newAccUserEmail"]); Помогите пожалуйста. Что не так с кодом?
@ADSoft, $db в данном случае скорее всего экземпляр класса mysqli https://www.php.net/manual/ru/class.mysqli.php
Там класс Database, а не mysqli Понятно, что ТС упомянул mysqli и пытается использовать одноименный с его метод, но как это связано с Database, ХЗ. --- Добавлено --- Наверное, обертка или наследник. Хотя наследник вряд ли.
А, точно, я проглючил Меня это обёртка ввела в заблуждение. Зачем нужна такая обёртка вообще? Я понимаю, если бы там были всякие методы валидации данных и какие-то конструкции из цепочек запросов для выполнения определенных задач...
Ага, тупо мог имя класса взять от имени подключаемого файла. --- Добавлено --- Нужна-нужна. И не только из-за патологической боязни, что мускулай тоже признают устаревшим --- Добавлено --- Недалекие PDO-шники любят рассказывать такие сказки... --- Добавлено --- Хотя ТС к нам прибежал не с ошибкой ненахождения класса
Спасибо за ответы ребята. Да есть отдельный класс Database.php он просто удобен, там многие методы прописаны такие как query и т д. Но к сожалению нет метода mysqli_real_escape_string. Класс не я писал, он в свободном доступе выложен был. В ПХП как вы уже поняли, я новичок. Потому и создал топик тут в этом разделе. С проблемой разобрался... Я оказывается совсем с головой не дружу. Запилил поле name в базу данных, а NULL по умолчанию, ему не прилепил. Код который тут работает полностью, просто дебагер юнити присылал билеберду, оказалось нужно было просто выставить NULL в дефолте name в phpmyadmin. А то он его хватал а там пусто... С авторизацией проблема ещё веселее получилась. Код поидее полностью работчий, но из POST присылается NULL в движке юнити, хотя в браузере код срабатывает как надо и присылает 0. Код прикреплю, может быть я в синтаксисе ошибся. А может задача оказалась не моего уровня знаний. Но... самое интересно что процедурный код РАБОТАЕТ оО Хотя те же данные принимает и отсылает и точно так же как и ООП стиль. Вобщем либо я сумасшедший, либо упустил что то очень важное. - Не рабочий ООП стиль. Код (Text): if(isset($_POST["loginUserEmail"])) { $email = $_POST["loginUserEmail"]; $password = $_POST["loginPassword"]; if($email != "" && $password != "") { $accounts = $db->query('SELECT * FROM accounts WHERE email = ? AND password = ?', $email, $password); $accounts->numRows(); // Подсчитываем кол-во строк. if ($accounts->numRows() > 0) { // Больше 0 сообщаем 1, пускаем в игру echo 1; }else{ echo 0; } }else{ echo "Оба поля обязательны.";} }else { echo "Успешное соединение"; } Рабочий процедурный: Код (Text): if(isset($_POST["loginUserEmail"])){ // Данные из поля $email = mysqli_real_escape_string($connection, $_POST["loginUserEmail"]); $password = mysqli_real_escape_string($connection, $_POST["loginPassword"]); if($email != "" && $password != ""){ //Check are entered username and password matched $sql = "SELECT * FROM accounts WHERE email = '$email' AND password = '$password'"; if(mysqli_num_rows(mysqli_query($connection, $sql)) > 0){ echo 1; }else{ echo 0; } }else{ echo "Оба поля обязательны."; } }else{ echo "Успешное соединение"; } Может быть профи увидят где я накосячил сравнив код и ткнут носом. Буду благодарен очень.
да не ООП у вас... не ООП... так попытка некоторые вещи обернуть в ООП... вставляете в нужном месте var_dump($_POST) к примеру и смотрите пришло ли у вас что-то? потом дальше смотрите - где какой результат... не рабочий - что значит в вашем понимании? ошибку дает? Какую? или что? ООП выглядел как нибудь-так PHP: User::login($_POST); //или $user->checkLogin() а метод бы реализовывал проверку авторизации
Я понимаю что такое ООП =) Если бы мне хватало знаний, я бы создал класс User и вот этот код пихнул бы в метод. К сожалению я пока не обладаю достаточным набором знаний в php в принципе, не только в ООП. Синтаксис ООП, вот наверное как правильно будет назвать мою попытку обернуть в ООП процедурный. Не рабочий, в моём понимании что он не работает. Никаких ошибок не выдаёт. При запуске кода из браузера, приходит результат 0. Как и должно приходить при пустой форме. Так как форма в Unity2D написана на C#. Я бы грешил на C# скрипт... но дело в том что процедурный код, который я приводил выше... выполняется полностью. Авторизирует юзера. Я поэтапно проверял весь "ООП" код через браузер. Он работает полностью... в браузере (а значит исключая POST приходящий из Unity) Интересно то, что в консоли Unity ошибка не отображается, хотя весь дебаггинг прописан. ПРиходит результат при нажатии на кнопку вхоад - NULL. И всё. Причина 100% в бэкэнде. Так как, повторюсь, C# скрипт прекрасно работает с процедурным кодом. Именно поэтому я просил профи в пхп сравнить два этих кода и возможно им удалось бы обнаружить где я ошибся. Возможно метод какой не так вызвал или ещё что то. Запятуи не там поставил... мало ли. Синтаксис я как раз сейчас и изучаю... с помощью вот этой задачи. Спасибо Вам за ответы. Всё таки буду надеятся на помощь потому что уже 2 вечер ковыряюсь и пробую всё подряд, результат тот же.
если ошибок не выдает - значит работает! другое дело как работает? так ли как задумано? ))) скорее всего дело где-то в PHP: $accounts = $db->query('SELECT * FROM accounts WHERE email = ? AND password = ?', $email, $password); $accounts->numRows(); // Подсчитываем кол-во строк. if ($accounts->numRows() > 0) { // Больше 0 сообщаем 1, пускаем в игру если б запятая или что было - вам бы php ругнулся... как реализован метод $db->query и $accounts->numRows()??? покажите его код
Процедурный код работает как должен. Да. Именно тут где то ошибка (или что это хз) кроется. Вот класс подключения и работы с БД. Код (Text): <?php $dbhost = 'localhost'; $dbuser = 'admin'; $dbpass = '123456'; $dbname = 'gamedb'; class Database { protected $connection; protected $query; protected $show_errors = TRUE; protected $query_closed = TRUE; public $query_count = 0; public function __construct($dbhost, $dbuser, $dbpass, $dbname, $charset = 'utf8') { $this->connection = new mysqli($dbhost, $dbuser, $dbpass, $dbname); if ($this->connection->connect_error) { $this->error('Failed to connect to MySQL - ' . $this->connection->connect_error); } $this->connection->set_charset($charset); echo "успешное подключение"; } public function query($query) { if (!$this->query_closed) { $this->query->close(); } if ($this->query = $this->connection->prepare($query)) { if (func_num_args() > 1) { $x = func_get_args(); $args = array_slice($x, 1); $types = ''; $args_ref = array(); foreach ($args as $k => &$arg) { if (is_array($args[$k])) { foreach ($args[$k] as $j => &$a) { $types .= $this->_gettype($args[$k][$j]); $args_ref[] = &$a; } } else { $types .= $this->_gettype($args[$k]); $args_ref[] = &$arg; } } array_unshift($args_ref, $types); call_user_func_array(array($this->query, 'bind_param'), $args_ref); } $this->query->execute(); if ($this->query->errno) { $this->error('Unable to process MySQL query (check your params) - ' . $this->query->error); } $this->query_closed = FALSE; $this->query_count++; } else { $this->error('Unable to prepare MySQL statement (check your syntax) - ' . $this->connection->error); } return $this; } public function fetchAll($callback = null) { $params = array(); $row = array(); $meta = $this->query->result_metadata(); while ($field = $meta->fetch_field()) { $params[] = &$row[$field->name]; } call_user_func_array(array($this->query, 'bind_result'), $params); $result = array(); while ($this->query->fetch()) { $r = array(); foreach ($row as $key => $val) { $r[$key] = $val; } if ($callback != null && is_callable($callback)) { $value = call_user_func($callback, $r); if ($value == 'break') break; } else { $result[] = $r; } } $this->query->close(); $this->query_closed = TRUE; return $result; } public function fetchArray() { $params = array(); $row = array(); $meta = $this->query->result_metadata(); while ($field = $meta->fetch_field()) { $params[] = &$row[$field->name]; } call_user_func_array(array($this->query, 'bind_result'), $params); $result = array(); while ($this->query->fetch()) { foreach ($row as $key => $val) { $result[$key] = $val; } } $this->query->close(); $this->query_closed = TRUE; return $result; } public function close() { return $this->connection->close(); } public function numRows() { $this->query->store_result(); return $this->query->num_rows; } public function affectedRows() { return $this->query->affected_rows; } public function lastInsertID() { return $this->connection->insert_id; } public function error($error) { if ($this->show_errors) { exit($error); } } private function _gettype($var) { if (is_string($var)) return 's'; if (is_float($var)) return 'd'; if (is_int($var)) return 'i'; return 'b'; } } ?>
Я не знаю поможет ли эта информация... вот распечатанный массив $account Код (Text): успешное подключениеУспешное соединениеDatabase Object ( [connection:protected] => mysqli Object ( [affected_rows] => -1 [client_info] => mysqlnd 7.4.21 [client_version] => 70421 [connect_errno] => 0 [connect_error] => [errno] => 0 [error] => [error_list] => Array ( ) [field_count] => 4 [host_info] => localhost via TCP/IP [info] => [insert_id] => 0 [server_info] => 8.0.24 [server_version] => 80024 [sqlstate] => 00000 [protocol_version] => 10 [thread_id] => 9 [warning_count] => 0 ) [query:protected] => mysqli_stmt Object ( [affected_rows] => -1 [insert_id] => 0 [num_rows] => 0 [param_count] => 2 [field_count] => 4 [errno] => 0 [error] => [error_list] => Array ( ) [sqlstate] => 00000 [id] => 1 ) [show_errors:protected] => 1 [query_closed:protected] => [query_count] => 1
Данные приходят из Unity, дебаг пхп пустой результат присылает потому что кнопка и поля находятся в Unity. А Unity присылает NULL. Хотя с процедурным кодом работает и авторизация срабатывает, отсюда можно сделать вывод что запрос POST точно улетает из Unity и дело не в C# скрипте, а в пхп коде переписаном в стиле ооп.
найдите способ отлаживать PHP, а то так и будете биться об стену 1 как вариант выводит отладочные переменные в файл например file_put_content('log.err',$email); 2. отправьте данные в скрипт php через обычную форму, или спец программу- например postman косяк может быть в любой строке кода... и пока не отладите прохождение данных - не сдвинетесь с места --- Добавлено --- например у вас тут по тексту в POST то POST['newAccUserEmail'] то POST['loginUserEmail']
POST данные улетают. Debug в Unity, это показывает с процедурным скриптом. По какой то причине бэкэнд (мой пхп скрипт) не принимает данные. Процедурный принимает, а значит ошибка где то в синтаксисе моего пхп скрипта переписанного под ооп стиль. Я подключал его по частям каждый метод, каждую переменную. И если проверять через браузер (сайт), ошибок нет. Данные пост, поступают. Методы работают, $accounts->numRows(); приносит как и должен результат 0 строк. Но если отправлять данные из Unity, они где то теряются. И это никак не проверить. Потому что до пхп скрипта они не доходят и пхп скрипт так и так сработает с результатом 0 строк, а в Unity дебаг присылает что данные не дошли, хоть он их и отправил и присылает Null. ПОпробую переписать часть кода... вот этого: Код (Text): if ($accounts->numRows() > 0) { echo 1; }else{ echo 0; Попробую поставить булеву переменную так как значения всё равно тут может быть только два тру или фалс. Благодарю вас за внимание к моей проблеме.
ну пусть покажет с новым скриптом - какие данные приходят в POST, не пойму - вы хотите проблему решить или как ежики - будете плакать, колоться но лезть на кактусы? ну как не проверить? не вывод не дает - подсказал, же - сохраняйте логи в файл... ну посмотрите что в $_POST вам приходит??
На скриншоте то что приходит в пост после отправки формы в пхп скрипт. Но... в скрипт пхп это всё НЕ доходит. Почему не знаю. И понятия не имею как проверить, просто потому что данные пост отправляются в Unity а не сайта. До сайта они не доходят. Скрипт же точно работает. Потому что при запуске его через браузер, он как и положено присылает 0 строк. То есть... он соединяется с БД отлично. Метод обработки полученных данных $accounts->numRows() прекрасно отрабатывает и показывает правильный результат строк. Проблема в том что ошибку, почему данные из Unity не доходят, никак не отследить потому что ИЗ Unity они отправляются, но В пхп скрипт они не доходят. То есть я могу сделать дебаг в движке (на скриншоте результат) и могу сделать дебаг в пхп скрипте, но данных там не будет потому что запускается вся телега из Unity. То есть отправляет данные. Без данных скрипт работает правильно. Почему он не получает POST из Unity я и не могу понять, так как названия полей, переменные... всё верно. И доказательство тому процедурный скрипт с теми же данными, который прекрасно работает. Вобщем решил распечатать что приходит вообще в принципе в Unity ответом от сервера... Переменная которая должна быть либо 0, либо 1 присылает массив который я выкладывал выше. Что то совсем уж несуразное. Переменная "responseText" в Unity которая должна принимать число строк в виде 0 или 1 принимает целый массив от пхп скрипта. Я помоему окончательно запутался.
Unity как сам движок я знаю. С C# знаний примерно столько же сколько с php. По сути только синтаксис освоил, и то не до конца. И в дополнение к предыдущему посту... через браузер $accounts->numRows(); присылает 0, как и положено. Никаких массивов оО Значит и в Unity отправляется количество столбцов правильное. Откуда же берётся массив, который записывается в переменную в Unity... ума не приложу.