За последние 24 часа нас посетили 21778 программистов и 1012 роботов. Сейчас ищут 669 программистов ...

Помогите с кодом. Переписываю процедурный в ООП

Тема в разделе "PHP для новичков", создана пользователем Nekomaru, 8 ноя 2021.

Метки:
  1. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Ребята, здравствуйте.
    Пытаюсь переписать процедурный код, в ООП. Столкнулся с проблемой экранирования функцией
    mysqli_real_escape_string. Хотя и есть сомнения что дело не в ней.
    Помогите разобраться пожалуйста. Код прилагаю.


    Код (Text):
    1.  
    2. <?php
    3. include "Database.php"; // Подключение класса БД
    4.  
    5. $db = new Database($dbhost, $dbuser, $dbpass, $dbname);
    6.  
    7. /******************************** Проверка при регистрации ****************************************** */
    8. if(isset($_POST["newAccUserEmail"])){ // Если существует запрос в переменной пост которая приходит из юнити
    9.  
    10.     $email = $db->real_escape_string($_POST["newAccUserEmail"]);
    11.  
    12.     $password = $db->real_escape_string($_POST["newAccPassword"]);
    13.  
    14.  
    15.     // Проверяем чтобы поля не были пустыми
    16.     if($email != "" && $password != ""){
    17.  
    18.         $account = $db->query('SELECT * FROM accounts WHERE email = ?', $email)->fetchArray();
    19.  
    20.         if ($account['email'] == 0) {
    21.  
    22.             $db->query('INSERT INTO accounts (email, password) VALUES (?,?)', $email, $password);
    23.  
    24.             echo "Регистрация: email " . $email . " and password: " . $password; // Текст который выводится в public Text info;
    25.  
    26.         }else{
    27.             echo "Этот email уже зарегистрирован.";
    28.         }      
    29.     }else{
    30.         echo "Оба поля обязательны. Введите свой email и придумайте пароль.";
    31.     }
    32. }
    33. /**********************************************************************************************************/
    Вот такой код я написал. В ООП из процедурного.
    Вот что выдаёт консоль при отправке данных в БД в юнити
    Код (Text):
    1. успешное подключение<br />
    2. Fatal error:  Uncaught Error: Call to undefined method Database::real_escape_string() in C:\OpenServer\domains\hstest.loc\index.php:49
    3. Stack trace:
    4. #0 {main}
    5.   thrown in C:\OpenServer\domains\hstest.loc\index.php on line 49<br />
    49 строка это: $email = $db->real_escape_string($_POST["newAccUserEmail"]);

    Помогите пожалуйста. Что не так с кодом?
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    В каком месте тут ООП?
    В вашем классе есть такой метод? Он вам напрямую говорит это
     
  3. KingdaKa

    KingdaKa Новичок

    С нами с:
    7 сен 2021
    Сообщения:
    87
    Симпатии:
    16
  4. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    какие ваши доказательства?
     
  5. KingdaKa

    KingdaKa Новичок

    С нами с:
    7 сен 2021
    Сообщения:
    87
    Симпатии:
    16
    Это _предположение_ :p Автор нам расскажет надеюсь.
     
  6. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Там класс Database, а не mysqli :p Понятно, что ТС упомянул mysqli и пытается использовать одноименный с его метод, но как это связано с Database, ХЗ.
    --- Добавлено ---
    Наверное, обертка или наследник. Хотя наследник вряд ли.
     
  7. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    Судя по тексту ошибки - на то ни другое ))
     
  8. KingdaKa

    KingdaKa Новичок

    С нами с:
    7 сен 2021
    Сообщения:
    87
    Симпатии:
    16
    А, точно, я проглючил :) Меня это обёртка ввела в заблуждение. Зачем нужна такая обёртка вообще? Я понимаю, если бы там были всякие методы валидации данных и какие-то конструкции из цепочек запросов для выполнения определенных задач...
     
  9. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Ага, тупо мог имя класса взять от имени подключаемого файла.
    --- Добавлено ---
    Нужна-нужна. И не только из-за патологической боязни, что мускулай тоже признают устаревшим :D
    --- Добавлено ---
    Недалекие PDO-шники любят рассказывать такие сказки...
    --- Добавлено ---
    Хотя ТС к нам прибежал не с ошибкой ненахождения класса :rolleyes:
     
  10. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Спасибо за ответы ребята.
    Да есть отдельный класс Database.php он просто удобен, там многие методы прописаны такие как query и т д.
    Но к сожалению нет метода mysqli_real_escape_string. Класс не я писал, он в свободном доступе выложен был.
    В ПХП как вы уже поняли, я новичок. Потому и создал топик тут в этом разделе.
    С проблемой разобрался...
    Я оказывается совсем с головой не дружу. Запилил поле name в базу данных, а NULL по умолчанию, ему не прилепил.
    Код который тут работает полностью, просто дебагер юнити присылал билеберду, оказалось нужно было просто выставить NULL в дефолте name в phpmyadmin. А то он его хватал а там пусто...

    С авторизацией проблема ещё веселее получилась. Код поидее полностью работчий, но из POST присылается NULL в движке юнити, хотя в браузере код срабатывает как надо и присылает 0.
    Код прикреплю, может быть я в синтаксисе ошибся. А может задача оказалась не моего уровня знаний. Но... самое интересно что процедурный код РАБОТАЕТ оО Хотя те же данные принимает и отсылает и точно так же как и ООП стиль. Вобщем либо я сумасшедший, либо упустил что то очень важное.

    - Не рабочий ООП стиль.
    Код (Text):
    1. if(isset($_POST["loginUserEmail"])) {
    2.    
    3.     $email = $_POST["loginUserEmail"];
    4.     $password = $_POST["loginPassword"];
    5.  
    6.     if($email != "" && $password != "") {
    7.         $accounts = $db->query('SELECT * FROM accounts WHERE email = ? AND password = ?', $email, $password);
    8.         $accounts->numRows(); // Подсчитываем кол-во строк.
    9.        
    10.         if ($accounts->numRows() > 0) { // Больше 0 сообщаем 1, пускаем в игру
    11.             echo 1;
    12.         }else{
    13.             echo 0;
    14.         }
    15.     }else{ echo "Оба поля обязательны.";}
    16. }else { echo "Успешное соединение"; }
    Рабочий процедурный:

    Код (Text):
    1. if(isset($_POST["loginUserEmail"])){ // Данные из поля
    2.     $email = mysqli_real_escape_string($connection, $_POST["loginUserEmail"]);
    3.     $password = mysqli_real_escape_string($connection, $_POST["loginPassword"]);
    4.     if($email != "" && $password != ""){
    5.         //Check are entered username and password matched
    6.         $sql = "SELECT * FROM accounts WHERE email = '$email' AND password = '$password'";
    7.         if(mysqli_num_rows(mysqli_query($connection, $sql)) > 0){
    8.             echo 1;
    9.         }else{
    10.             echo 0;
    11.         }
    12.     }else{
    13.         echo "Оба поля обязательны.";
    14.     }
    15. }else{
    16.     echo "Успешное соединение";
    17. }
    Может быть профи увидят где я накосячил сравнив код и ткнут носом. Буду благодарен очень.
     
  11. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    да не ООП у вас... не ООП... так попытка некоторые вещи обернуть в ООП...

    вставляете в нужном месте var_dump($_POST) к примеру и смотрите пришло ли у вас что-то?
    потом дальше смотрите - где какой результат...

    не рабочий - что значит в вашем понимании? ошибку дает? Какую? или что?

    ООП выглядел как нибудь-так
    PHP:
    1. User::login($_POST);
    2. //или
    3. $user->checkLogin()
    а метод бы реализовывал проверку авторизации
     
  12. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Я понимаю что такое ООП =) Если бы мне хватало знаний, я бы создал класс User и вот этот код пихнул бы в метод. К сожалению я пока не обладаю достаточным набором знаний в php в принципе, не только в ООП. Синтаксис ООП, вот наверное как правильно будет назвать мою попытку обернуть в ООП процедурный.

    Не рабочий, в моём понимании что он не работает. Никаких ошибок не выдаёт. При запуске кода из браузера, приходит результат 0. Как и должно приходить при пустой форме. Так как форма в Unity2D написана на C#.
    Я бы грешил на C# скрипт... но дело в том что процедурный код, который я приводил выше... выполняется полностью. Авторизирует юзера.

    Я поэтапно проверял весь "ООП" код через браузер. Он работает полностью... в браузере (а значит исключая POST приходящий из Unity)
    Интересно то, что в консоли Unity ошибка не отображается, хотя весь дебаггинг прописан. ПРиходит результат при нажатии на кнопку вхоад - NULL. И всё.

    Причина 100% в бэкэнде. Так как, повторюсь, C# скрипт прекрасно работает с процедурным кодом.

    Именно поэтому я просил профи в пхп сравнить два этих кода и возможно им удалось бы обнаружить где я ошибся. Возможно метод какой не так вызвал или ещё что то. Запятуи не там поставил... мало ли. Синтаксис я как раз сейчас и изучаю... с помощью вот этой задачи.
    Спасибо Вам за ответы. Всё таки буду надеятся на помощь потому что уже 2 вечер ковыряюсь и пробую всё подряд, результат тот же.
     
  13. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    если ошибок не выдает - значит работает!
    другое дело как работает? так ли как задумано? )))

    скорее всего дело где-то в
    PHP:
    1. $accounts = $db->query('SELECT * FROM accounts WHERE email = ? AND password = ?', $email, $password);
    2.         $accounts->numRows(); // Подсчитываем кол-во строк.
    3.    
    4.         if ($accounts->numRows() > 0) { // Больше 0 сообщаем 1, пускаем в игру
    если б запятая или что было - вам бы php ругнулся...

    как реализован метод $db->query и $accounts->numRows()???
    покажите его код
     
  14. KingdaKa

    KingdaKa Новичок

    С нами с:
    7 сен 2021
    Сообщения:
    87
    Симпатии:
    16
    @ADSoft, хватит выпендриваться, новичкам настрой сбивать, а профи не оценят... :p
     
  15. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Процедурный код работает как должен.
    Да. Именно тут где то ошибка (или что это хз) кроется. Вот класс подключения и работы с БД.

    Код (Text):
    1. <?php
    2. $dbhost = 'localhost';
    3. $dbuser = 'admin';
    4. $dbpass = '123456';
    5. $dbname = 'gamedb';
    6.  
    7. class Database {
    8.  
    9.     protected $connection;
    10.     protected $query;
    11.     protected $show_errors = TRUE;
    12.     protected $query_closed = TRUE;
    13.     public $query_count = 0;
    14.  
    15.     public function __construct($dbhost, $dbuser, $dbpass, $dbname, $charset = 'utf8') {
    16.         $this->connection = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
    17.         if ($this->connection->connect_error) {
    18.             $this->error('Failed to connect to MySQL - ' . $this->connection->connect_error);
    19.         }
    20.         $this->connection->set_charset($charset);
    21.         echo "успешное подключение";
    22.     }
    23.  
    24.     public function query($query) {
    25.         if (!$this->query_closed) {
    26.             $this->query->close();
    27.         }
    28.         if ($this->query = $this->connection->prepare($query)) {
    29.             if (func_num_args() > 1) {
    30.                 $x = func_get_args();
    31.                 $args = array_slice($x, 1);
    32.                 $types = '';
    33.                 $args_ref = array();
    34.                 foreach ($args as $k => &$arg) {
    35.                     if (is_array($args[$k])) {
    36.                         foreach ($args[$k] as $j => &$a) {
    37.                             $types .= $this->_gettype($args[$k][$j]);
    38.                             $args_ref[] = &$a;
    39.                         }
    40.                     } else {
    41.                         $types .= $this->_gettype($args[$k]);
    42.                         $args_ref[] = &$arg;
    43.                     }
    44.                 }
    45.                 array_unshift($args_ref, $types);
    46.                 call_user_func_array(array($this->query, 'bind_param'), $args_ref);
    47.             }
    48.             $this->query->execute();
    49.                if ($this->query->errno) {
    50.                 $this->error('Unable to process MySQL query (check your params) - ' . $this->query->error);
    51.                }
    52.             $this->query_closed = FALSE;
    53.             $this->query_count++;
    54.         } else {
    55.             $this->error('Unable to prepare MySQL statement (check your syntax) - ' . $this->connection->error);
    56.         }
    57.         return $this;
    58.     }
    59.  
    60.  
    61.     public function fetchAll($callback = null) {
    62.         $params = array();
    63.         $row = array();
    64.         $meta = $this->query->result_metadata();
    65.         while ($field = $meta->fetch_field()) {
    66.             $params[] = &$row[$field->name];
    67.         }
    68.         call_user_func_array(array($this->query, 'bind_result'), $params);
    69.         $result = array();
    70.         while ($this->query->fetch()) {
    71.             $r = array();
    72.             foreach ($row as $key => $val) {
    73.                 $r[$key] = $val;
    74.             }
    75.             if ($callback != null && is_callable($callback)) {
    76.                 $value = call_user_func($callback, $r);
    77.                 if ($value == 'break') break;
    78.             } else {
    79.                 $result[] = $r;
    80.             }
    81.         }
    82.         $this->query->close();
    83.         $this->query_closed = TRUE;
    84.         return $result;
    85.     }
    86.  
    87.     public function fetchArray() {
    88.         $params = array();
    89.         $row = array();
    90.         $meta = $this->query->result_metadata();
    91.         while ($field = $meta->fetch_field()) {
    92.             $params[] = &$row[$field->name];
    93.         }
    94.         call_user_func_array(array($this->query, 'bind_result'), $params);
    95.         $result = array();
    96.         while ($this->query->fetch()) {
    97.             foreach ($row as $key => $val) {
    98.                 $result[$key] = $val;
    99.             }
    100.         }
    101.         $this->query->close();
    102.         $this->query_closed = TRUE;
    103.         return $result;
    104.     }
    105.  
    106.     public function close() {
    107.         return $this->connection->close();
    108.     }
    109.  
    110.     public function numRows() {
    111.         $this->query->store_result();
    112.         return $this->query->num_rows;
    113.     }
    114.  
    115.     public function affectedRows() {
    116.         return $this->query->affected_rows;
    117.     }
    118.  
    119.     public function lastInsertID() {
    120.         return $this->connection->insert_id;
    121.     }
    122.  
    123.     public function error($error) {
    124.         if ($this->show_errors) {
    125.             exit($error);
    126.         }
    127.     }
    128.  
    129.     private function _gettype($var) {
    130.         if (is_string($var)) return 's';
    131.         if (is_float($var)) return 'd';
    132.         if (is_int($var)) return 'i';
    133.         return 'b';
    134.     }
    135.  
    136. }
    137. ?>
     
  16. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Я не знаю поможет ли эта информация... вот распечатанный массив $account

    Код (Text):
    1. успешное подключениеУспешное соединениеDatabase Object
    2. (
    3.     [connection:protected] => mysqli Object
    4.         (
    5.             [affected_rows] => -1
    6.             [client_info] => mysqlnd 7.4.21
    7.             [client_version] => 70421
    8.             [connect_errno] => 0
    9.             [connect_error] =>
    10.             [errno] => 0
    11.             [error] =>
    12.             [error_list] => Array
    13.                 (
    14.                 )
    15.  
    16.             [field_count] => 4
    17.             [host_info] => localhost via TCP/IP
    18.             [info] =>
    19.             [insert_id] => 0
    20.             [server_info] => 8.0.24
    21.             [server_version] => 80024
    22.             [sqlstate] => 00000
    23.             [protocol_version] => 10
    24.             [thread_id] => 9
    25.             [warning_count] => 0
    26.         )
    27.  
    28.     [query:protected] => mysqli_stmt Object
    29.         (
    30.             [affected_rows] => -1
    31.             [insert_id] => 0
    32.             [num_rows] => 0
    33.             [param_count] => 2
    34.             [field_count] => 4
    35.             [errno] => 0
    36.             [error] =>
    37.             [error_list] => Array
    38.                 (
    39.                 )
    40.  
    41.             [sqlstate] => 00000
    42.             [id] => 1
    43.         )
    44.  
    45.     [show_errors:protected] => 1
    46.     [query_closed:protected] =>
    47.     [query_count] => 1
     
  17. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    а $email, $password перед запросом выведите? Что там?
     
  18. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Данные приходят из Unity, дебаг пхп пустой результат присылает потому что кнопка и поля находятся в Unity. А Unity присылает NULL. Хотя с процедурным кодом работает и авторизация срабатывает, отсюда можно сделать вывод что запрос POST точно улетает из Unity и дело не в C# скрипте, а в пхп коде переписаном в стиле ооп.
     
  19. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    найдите способ отлаживать PHP, а то так и будете биться об стену
    1 как вариант выводит отладочные переменные в файл например file_put_content('log.err',$email);
    2. отправьте данные в скрипт php через обычную форму, или спец программу- например postman

    косяк может быть в любой строке кода... и пока не отладите прохождение данных - не сдвинетесь с места
    --- Добавлено ---
    например у вас тут по тексту в POST то POST['newAccUserEmail'] то POST['loginUserEmail']
     
  20. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    POST данные улетают. Debug в Unity, это показывает с процедурным скриптом. По какой то причине бэкэнд (мой пхп скрипт) не принимает данные.
    Процедурный принимает, а значит ошибка где то в синтаксисе моего пхп скрипта переписанного под ооп стиль. Я подключал его по частям каждый метод, каждую переменную. И если проверять через браузер (сайт), ошибок нет. Данные пост, поступают. Методы работают, $accounts->numRows(); приносит как и должен результат 0 строк.
    Но если отправлять данные из Unity, они где то теряются. И это никак не проверить. Потому что до пхп скрипта они не доходят и пхп скрипт так и так сработает с результатом 0 строк, а в Unity дебаг присылает что данные не дошли, хоть он их и отправил и присылает Null.
    ПОпробую переписать часть кода... вот этого:

    Код (Text):
    1. if ($accounts->numRows() > 0) {
    2.  echo 1;        }else{         echo 0;
    Попробую поставить булеву переменную так как значения всё равно тут может быть только два тру или фалс. Благодарю вас за внимание к моей проблеме.
     
  21. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.822
    Симпатии:
    736
    Адрес:
    Татарстан
    ну пусть покажет с новым скриптом - какие данные приходят в POST, не пойму - вы хотите проблему решить или как ежики - будете плакать, колоться но лезть на кактусы?

    ну как не проверить? не вывод не дает - подсказал, же - сохраняйте логи в файл... ну посмотрите что в $_POST вам приходит??
     
  22. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    На скриншоте то что приходит в пост после отправки формы в пхп скрипт.
    Но... в скрипт пхп это всё НЕ доходит. Почему не знаю. И понятия не имею как проверить, просто потому что данные пост отправляются в Unity а не сайта. До сайта они не доходят.
    Скрипт же точно работает. Потому что при запуске его через браузер, он как и положено присылает 0 строк. То есть... он соединяется с БД отлично. Метод обработки полученных данных $accounts->numRows() прекрасно отрабатывает и показывает правильный результат строк.

    Проблема в том что ошибку, почему данные из Unity не доходят, никак не отследить потому что ИЗ Unity они отправляются, но В пхп скрипт они не доходят. То есть я могу сделать дебаг в движке (на скриншоте результат) и могу сделать дебаг в пхп скрипте, но данных там не будет потому что запускается вся телега из Unity. То есть отправляет данные.
    Без данных скрипт работает правильно. Почему он не получает POST из Unity я и не могу понять, так как названия полей, переменные... всё верно. И доказательство тому процедурный скрипт с теми же данными, который прекрасно работает.

    Вобщем решил распечатать что приходит вообще в принципе в Unity ответом от сервера...
    Переменная которая должна быть либо 0, либо 1 присылает массив который я выкладывал выше. Что то совсем уж несуразное. Переменная "responseText" в Unity которая должна принимать число строк в виде 0 или 1 принимает целый массив от пхп скрипта.
    Я помоему окончательно запутался.
     

    Вложения:

    • debug.jpg
      debug.jpg
      Размер файла:
      61,4 КБ
      Просмотров:
      2
    #22 Nekomaru, 11 ноя 2021
    Последнее редактирование: 11 ноя 2021
  23. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    A Unity вы также знаете, как PHP?

    Вообще, всякие апихи отлаживаются через Postman и аналоги
     
  24. Nekomaru

    Nekomaru Активный пользователь

    С нами с:
    3 дек 2015
    Сообщения:
    14
    Симпатии:
    0
    Unity как сам движок я знаю. С C# знаний примерно столько же сколько с php. По сути только синтаксис освоил, и то не до конца.

    И в дополнение к предыдущему посту... через браузер $accounts->numRows(); присылает 0, как и положено. Никаких массивов оО Значит и в Unity отправляется количество столбцов правильное. Откуда же берётся массив, который записывается в переменную в Unity... ума не приложу.