• Какова роль интерфейсов в ООП?

    Приведу пример на коленке. Хотим, например, написать абстрактную файловую систему. Для начала, определим интерфейс, для ФС:

    interface FileSystemInterface {
      public function write($file, $data);
      public function read($file);
    }


    Затем, хочу реализацию интерфейса ФС для работы с файликами:

    class OSFileSystem implements FileSystemInterface {
      public function write($file, $data) {
         // открываем файлик, пишем данные
      }
    
      public function read($file) {
        // открываем файлик, возвращаем данные
      }
    }


    Вдруг, кому-то захотелось файловую систему в облаке. Окей, не проблема, реализуем это:
    class CloudFileSystem implements FileSystemInterface {
      public function write($file, $data) {
         // открываем соединение с облаком, пишем данные
      }
    
      public function read($file) {
        // открываем соединение с облаком, возвращаем данные
      }
    }

    Пусть у нас есть кой-то код, работающий с файловой системой, назовем его "Хранилище файлов". Пусть он выглядит примерно так:

    class FileStorage {
      protected $Fs;
      
      public function __construct(FileSystemInterface $Fs) {
        $this->Fs = $Fs;
      }  
    
      public function saveFile() {
        $this->Fs->write('file.txt', 'file data');
      }
    
      public function getFile() {
        return $this->Fs->read('file.txt', 'file data');
      }
    }


    Отлично! Теперь мы можем хранилищу файлов отдать любой объект с реализованным интерфейсом FileSystemInterface. Пример:

    // Хранилище файлов работает с файловой системой ОС:
    $FS = new OSFileSystem();
    $FileStorage = new FileStorage($Fs);
    $FileStorage->getFile();
    
    // Хранилище файлов работает с файловой системой в облаке:
    $FS = new CloudFileSystem();
    $FileStorage = new FileStorage($Fs);
    $FileStorage->getFile();


    Использование интерфейса, в данном случае. позволяет нам писать только реализацию работы файловой системы, а бизнес-логика, работающая с файловой системой никак не меняется, она знает, что в любом случае файловая система реализует интерфейс FileSystemInterface и может без опаски использовать методы этого интерфейса.
    Ответ написан
    14 комментариев
  • Чем отличаются self::, parent:: и static:: в PHP?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    Позднее связывание — это значит привязка будет происходит не на этапе компиляции кода, а на этапе его исполнения.
    В примере Кирилл Арутюнов это видно — self всегда указывает на тот класс, в котором оно объявлено, а static — на класс в котором он по факту будет вызван с учетом всех наследований.
    Ответ написан
    Комментировать
  • Чем отличаются self::, parent:: и static:: в PHP?

    arutyunov
    @arutyunov
    Mooza.ru — Делаем сайты
    Проще объяснить на примере:

    class A {
      public static function getValSelf()
      {
      	return new self();
      }
    
      public static function getValStatic()
      {
      	return new static();
      }
    }
    
    Class B extends A {
    }
    
    var_dump(get_class(B::getValSelf())); // 'A'
    var_dump(get_class(B::getValStatic())); // 'B'
    Ответ написан
    Комментировать
  • Почему не читаются куки?

    JhaoDa
    @JhaoDa
    LaravelRUS Team
    Документацию надо читать, её для этого писали. И в код заглядывать бояться не надо.
    Ответ написан
    3 комментария
  • Почему не добавляется ещё один LEFT JOIN?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    ... WHERE city_id = 4019 LEFT JOIN ...
    После WHERE не может быть JOIN'ов.
    Ответ написан
    5 комментариев
  • Как вывести категорию для постов?

    @potkot
    PHP программист
    Я делал примерно так

    Модель для статей:
    class Articles extends Model
    {
        protected $table = 'article';
    
        public function category()
        {
            return $this->belongsTo('ArticlesCategory', 'id_category', 'id');
        }
    }


    Модель для категорий:
    class ArticlesCategory extends Model
    {
        protected $table = 'article_category';
    
        public function articles()
        {
            return $this->hasMany('Articles', 'id_category', 'id');
        }
    }


    Получаем статьи с категориями в контроллере
    Articles::with('category')->paginate(25);

    В шаблоне так:
    $article->category->name
    Ответ написан
    Комментировать
  • Как вывести записи пивотной таблицы, с пагинатором?

    @Yadalay
    Php, Mysql, Html, Css, Js/Jquery/Ajax, Laravel
    $aaa = Category::find(3);
       
    dd($aaa->article()->paginate(2));
    Ответ написан
    Комментировать
  • Краткий тест для web-разработчика?

    Stalker_RED
    @Stalker_RED
    Не нужно ничего выдумывать.
    Двайте им одну-две реальные задачи из вашей работы. Может не целиком лендинг, а например"сверстать форму обратной связи" или "сделать модуль для email рассылки на 2000 адресов", или что там у вас считается за нестандартные задачи.

    Вот прямо откройте историю, выберите несколько тасков на 2-4 часа, и готово.

    Можно даже им оплатить, если это пройдет в прод.
    Ответ написан
    9 комментариев
  • Как добавить статью в базу, через REST API Laravel?

    @Artem0071
    Безработный mr. Junior
    Если прописывали в api.php, то обращаться нужно к 127.0.0.1:8000/api/task
    Ответ написан
    Комментировать
  • Как сохранить разметку, после загрузки ajax?

    @Koteezy
    Ctrl+u показывает исходный код страницы, как если бы, она была загружена в первый раз, без аяксов, и каких либо изменений дом дерева
    Ответ написан
    Комментировать
  • Как сделать точку входа на сайт?

    ThunderCat
    @ThunderCat
    {PHP, MySql, HTML, JS, CSS} developer
    RewriteRule !\.(js|ico|gif|jpg|png|css|pdf|mov|mp3|woff2)$ index.php
    Ответ написан
    1 комментарий
  • Почему не вызывается статический метод?

    shaks
    @shaks
    Дык, батенька) во первых.
    public function __destruct() {
          $this->log('Создался объект');


    не "создался", а уничтожился. раз, не $this->log а self::$log два. (у тебя ж статический метод то)
    И ты хоть 20 раз напиши в конце файла FileLogger::create('test', "file.log");, записей больше не увидишь. Объясняю почему:

    Деструктор класса срабатывает когда? правильно, когда разрушается объект. А объект у тебя разрушается когда? правильно, когда завершается работа скрипта. А разрушается он 1 раз а не 3 почему? потому что объект у тебя один.
    Взгляни внимательно на функцию create , особенно на эту запись
    if(isset(self::$loggers[$fname])) {
          
            return self::$loggers[$fname];
          }

    и обрати внимание какое имя файла ты передаешь своему логгеру и да придет тебе озарение юный падаван.

    !! Для более глубокого понимания, советую поставить xdebug, и глянуть пошагово что происходит и как.

    P.S. Не вздумай даже этот логгер использовать гдето на практике. Автор видимо хотел чтото объяснить этим кодом, а не написать логгер. Ибо это дичь.
    Ответ написан
    Комментировать
  • Как правильно реализовать ООП класс базы данных с PDO?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Я уже отвечал как-то на подобный вопрос. И не один раз. И не два.
    Поскольку мозги всех пользователей пхп ходят по одним и тем же рельсам, не сворачивая. Впрочем, не всех. 85% всю жизнь продолжают писать mysl_query, которую выучили из видеоурока, и не видят в этом проблем. И только у самых талантливых 15-и процентов в какой-то момент возникает мысль ВСЁ АВТОМАТИЗИРОВАТЬ. Это, на самом деле, хороший знак. Такое желание как раз и отличает потенциального программиста от клепальщика гуано-кода.

    Но всё портит недостаток знаний в SQL. Искренне полагая SQL не более чем key-value хранилищем, они всерьез уверены в том, что функция select() с двумя аргументами - это все что им надо.

    Настоятельно рекомендую прочесть аргументацию по ссылке выше.

    После этого понять, что существует ТРИ класса классов для работы с БД:

    1. DB-хелпер. Класс, берущий на себя всю грязную работу по исполнению запросов. В случае с ПДО не сильно-то и нужен. Позволяет исполнять любые запросы. НИКАКИХ функций типа select(), ограничивающих функциональность, в нем быть не должно ни в коем случае.
    2. Query builder. Функция типа select() может быть только в квери билдере, который маскирует SQL в функции РНР. Заведомо ущербен по сравнению с первым, но зато позволяет использовать запросы более сложные, чем ORM.
    3. ORM. То, что начинающему пользователю на самом деле нужно, но он об этом просто не догадывается. Как раз та самая волшебная палочка, которая делает примитивное доставание данных из базы по первичному ключу столь маняще единообразным.

    Cамое главное, что надо понять:
    Все вышеперечисленное - это РАЗНЫЕ типы классов, не имеющие между собой ничего общего.
    И не пытаться под видом первого городить нежизнеспособное второе, имея в виду третье. Надо очень четко понимать, что сначала делаем первое, а потом, на его основе - либо второе, либо третье. Но не все вместе.

    А можно не пытаться изобретать велосипед, а использовать готовое. Например - популярный фреймворк. Тогда желаемая функция будет выглядеть вот так:

    public function viewUser($id)
    {
        return User::model()->findByPk($id);
    }

    Это в самом предпочтительном случае - при использовании ORM.
    На квери билдере это будет что-то вроде
    public function viewUser($id)
    {
        return DB::select('*')->from('users')->where("id", '=', $id);
    }


    При этом можно использовать и чистый SQL. Запрос прямо в классе юзера - это не так уж и страшно. Тем более, что есть такие запросы, которые по другому просто не выполнишь. Другое дело, что всю работу по исполнению запроса должен брать на себя хелпер. Пример можно посмотреть по ссылке выше - там хоть и SQL , но того ужаса, который здесь, нету:
    public function viewUser($id)
    {
        $sql = 'SELECT * FROM users WHERE id=?';
        return DB::prepare($sql)->execute([$id])->fetch();
    }
    Дальнейшую работы над классом можно производить только после того как ты определишься, какой именно класс ты хочешь написать.
    Ответ написан
  • Почему ругается на создание объекта?

    @D3lphi
    Поиграем в игру "Найди 10 отличий"?
    $loggers
    $logers
    Ответ написан
    Комментировать