За последние 24 часа нас посетили 51950 программистов и 1772 робота. Сейчас ищут 865 программистов ...

Наследование классов

Тема в разделе "PHP для новичков", создана пользователем Stairdeck, 14 июн 2016.

  1. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Здравствуйте!
    Столкнулся с проблемой:
    Код (Text):
    1. Call to a member function query() on null in /home/home/web/site.ru/public_html/classes/user.class.php on line 40, referer: http://site.ru/index.php?do=register
    Разобрался в чем дело, в той функции, где ошибка идет на функцию запроса:
    PHP:
    1. public function register($username, $password, $ip, $email)
    2.             {
    3.  
    4.                 $db->query("INSERT INTO users SET user_login='".htmlspecialchars($username)."', user_password='".htmlspecialchars($password)."', user_ip='".$ip."', user_email='".htmlspecialchars($email)."'");
    5.                 return true;
    6.             }
    7.  
    8. //Это метод регистрации в классе юзеров
    Не ссылается $db->query на объект. У меня пока что существует 2 класса, для работы с бд и юзерами.
    Так вот в классе с юзерами, как Вы видите, используются методы из класса бд. Вопрос, как подключить класс бд к классу юзеров? Вид index страницы у меня сейчас такой:

    PHP:
    1. include_once "classes/head/mysql.php";
    2.  
    3. $db = new db();
    4.  
    5. include_once "classes/user.class.php";
    6.  
    7. include_once "engine/register.php"; //В нем метод на регистрацию класса юзеров
     
  2. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Ну так глобальные переменные не доступны по умолчанию, надо использовать ключевое слово global
     
  3. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    По какой книге изучаешь PHP и MySQL?
    Я вижу проблемы с безопасностью, sql-injection.
     
  4. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Где тут глобальные переменные?
    Ещё вообще ничего не читал по этому поводу. Пытаюсь как-то ООП пока хоть немного понять. Есть хорошая литература на эту тему? А что, уязвимостей много?
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    $db у тебя глобальная переменная, судя по второму листингу, а в первом ты её не указываешь как global. Кстати, сообщение об ошибке с английского ты перевёл неверно
    --- Добавлено ---
    По поводу уязвимостей - традиционный, кем-то распространённый по рунету идиотизм, что нужно перед вставкой делать htmlspecialchars. Спрашивается, зачем, если база html не понимает? Экранировать надо те символы, которые база понимает и может понять ошибочно, а это функции типа mysqli_escape_string, PDO::quote, а также подготовленные запросы
     
  6. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Я не переводил ошибку, лишь погуглил причину её появления. И да, $db - не глобальная переменная, а объект, принадлежащий классу db
    --- Добавлено ---
    Спасибо за mysqli_escape_string
     
  7. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Вот тут ты не прав. $db - это глобальная переменная, содержащая ссылку на объект класса db. Доступ к объектам тоже осуществляется через переменные. В некоторых языках (C++, к примеру), объекты могут храниться прямо в переменных, а в других, как PHP, в переменных сохраняется только ссылка на объект
     
  8. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Хорошо, как тогда правильно объявить?
     
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    Уже 5 раз писал - указать её в методе с ключевым словом global.
     
    Stairdeck нравится это.
  10. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Советую поискать книги по PHP для начинающих, про ООП так же. Главное по свежее книги читать.
    http://phpfaq.ru/mysql/slashes
     
    Stairdeck нравится это.
  11. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Спасибо, помогло.
     
  12. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Не лучше ли через конструктор передавать объект БД. А то создавать такую зависимость не хорошо.

    PHP:
    1. class MyClass{
    2.     private $db;
    3. function __construct(\PDO $db){
    4.     $this->db = $db;
    5. }
    6.  
    7. $db = new \PDO();
    8. $class = new MyClass($db);
    Или воспользоваться паттерном проектирования Registry, Singleton
     
    romach нравится это.
  13. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @mahmuzar, лучше. Хотя вы тоже создали зависимость. И с синглтоном или Registry зависимость всё равно будет. Но, лично я считаю, что если глобальных переменных 1-2, то это тоже не самое страшное. А челу тут не до паттернов. Я не буду рассказывать про паттерны человеку, который не знает, как пользоваться global.
     
    mahmuzar нравится это.
  14. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Раз делает по ООП то дать направление в сторону ООП посчитал нужным. Зависимость она всегда есть.
     
  15. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
  16. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @romach, не в качестве спора, но просто: в чём принципиальная разница между f1() и f2()
    PHP:
    1. function f1() {
    2.    global $app;
    3.    $app["db"]->query(/* ... */);
    4. }
    5.  
    6. function f2() {
    7.     \Yii::$app->db->createCommand(/* ... */)->execute();
    8. }
    По мне, по барабану.
    --- Добавлено ---
    Первый подход, кстати, постоянно в Silex нужно использовать. В том или ином виде.
     
  17. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Короче с глобальными переменными тоже не хорошо делать? Придется разбираться в том, что Вы только что написали
     
  18. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @Stairdeck если глобальная переменная только одна, то это не так страшно, на мой взгляд. если больше 5 - то караул. romach дпугого мнения придерживается, но это мнение. Но можешь почитать про паттерны. Мэтт Зандстра. "PHP: объекты, шаблоны и методики программирования". Только боюсь, что для начала надо про язык ещё раз прочитать
     
  19. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    @mkramer в данном примере - ни чем, кроме как лишней строчкой на каждом углу. В первом примере мы имеем контейнер с хорошо документированным интерфейсом доступа и юзекейсами. Кстати, я не любитель silex, но когда писал на нем, то обернул это дело, во имя удобства, автоподстоновок и отсутствия глобалов )

    Может я резко выразился, речь шла про создание объекта класса, которое ты таскаешь за собой везде и всюду, пока где-нибудь он не затрется. Думаю ты и сам в курсе, в какой адский геморрой это может вылиться.
     
  20. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    @romach мне лишь нужно, чтобы методы работы с базами данных работали в методах класса работы с пользователями. Как это можно реализовать с помощью синглотона?
     
  21. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    хм... вообще, для работы с хранилищами данных нужно делать модели, которые в свою очередь не будут делать ничего, кроме предоставления интерфейса доступа. Сами действия и прочую бизнес-логику лучше выносить в сервисный слой, к которому и будет обращаться ваше приложение для выполнения нужных задач. Гуглить на тему "сервисный слой" / "service layer".

    p.s. тут нужно учитывать, что подходы бывают разные, спорные, со своими недостатками, достоинствами и областью применения. Лучше для начала займитесь синтаксисом языка, почитайте книжку, которую порекомендовал @mkramer и просто сделайте так что бы работало. Остальное придет с опытом.
     
  22. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    Я понял, почему нужно использовать синглтон. Однако, я планирую только 1 раз вызывать $bd = new bd(); Не грешно использовать Глобал или все-таки попытаться реализовать через паттерн? И да, на счёт работоспособности. Все работает
     
  23. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    На твоём уровне сойдёт и global. Хотя твой db легко можно и в синглтон преобразовать. С тобой тяжело говорить о таких вещах, поскольку ты ещё не настолько знаешь. Вон, @romach уже стал о моделях и сервисном слое говорить, я ты путаешься в простых вещах, типа что является переменной, а что нет. Короче, в этом проекте оставь как есть, а на будущее - почитай и про язык, и про паттерны, чтоб уже с тобой можно было на одном языке говорить.
     
  24. Stairdeck

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

    С нами с:
    9 ноя 2014
    Сообщения:
    47
    Симпатии:
    0
    Адрес:
    Россия
    @mkramer Ладно, спасибо за советы, во всяком случае.