• Как перенять объектно-ориентированное мышление?

    tzlom
    @tzlom
    Очень просто.
    Для начала - признайтесь себе что процедурное программирование у вас тоже страдает (иначе бы у вас не было этого вопроса), это не страшно, но с этим тоже надо что-то решать.
    Берёте любой свой процедурный проект (лучше маленький чтобы не застрять в рутине).
    Шаг первый - всё есть функция, поэтому весь код вне функций кладёте в функции, итого у вас получается что вне функций идёт только вызов main() (или как вы её назовёте)
    Второй шаг - функции работают только с тем, что в них передали. Удаляете глобальные переменные.
    Появляется проблема глубокой вложености, т.е. у вас внутри вызова А вызывается Б а в ней В которая хочет переменную из области видимости А, и таких случаев много. Тащить в Б все эти переменные - грустно и печально, поэтому делаем хитрость, каждая функция первым аргументом получает массив неких значений. Правило одно - функции не меняют имена и количество переменных в массиве, только значения.
    Третий шаг - функции должны быть короткими, выносите повторяющийся код в отдельные функции, если в функции используется много переменных - это повод разбить её на несколько меньших.
    Четвёртый шаг - вы уже пишете на ООП. Если 3 шага правильно сделаны, то осталось только оформить это дело согласно новым правилам - первый аргумент-массив это члены класса, соответственно функции использующие одинаковый массив - методы этого класса, прийдётся разобраться с доступом к полям и отдельными зависимостями, но это уже будет просто и понятно когда ты до этого доберёшься.
    Ответ написан
    4 комментария
  • Как и где хранить роуты?

    php666
    @php666
    PHP-макака
    ссылка про роуты
    там два варианта - роут по принципу наименования как физического файла класса, так и с описанием (виртуальный) как у тебя.

    В своем проекте сделал хранение роутов в базе данных
    это глупость. это никому не нужно. роут не должен никак зависеть от базы. она может быть вообще недоступна. нет ни одной причины класть роуты в базу.
    Ответ написан
    7 комментариев
  • Как и где хранить роуты?

    dmitriylanets
    @dmitriylanets
    веб-разработчик
    часть роутеров (админ, ajax) конфигурирую через конфиг, публичные роутеры в бд
    Ответ написан
    Комментировать
  • Как и где хранить роуты?

    @cpanelhostig
    hosting, php dev
    В своем движке храню роуты в бд, но они при изменении скриптом пишутся в конфиг nginx. Так намного быстрее работает. При использовании apache движок создант записи в .htccess.
    Ответ написан
    Комментировать
  • Правильно ли я понимаю суть Интерфейсов в ООП?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Интерфейс — основа полиморфизма.
    Есть один интерфейс, с ним умеет работать некий код. Вуаля, любая реализация этого интерфейса подходит для этого самого кода.

    Пример: есть некий класс заказа Order, он работает с неким отправителем Sender, мы можем жестко "научить" его работать с ним в коде этого Order, а можем просто передавать ему отправителя через конструктор (привет DI), но передавать не сам класс/реализацию, а лишь его абстракцию — интерфейс, то, что будет отправлять, но как — не важно, это будет SenderInterface.

    Теперь мы в Order можем юзать полиморфизм: использовать любой Sender, который реализует этот самый SenderInterface

    Код:
    interface SenderInterface
    {
         public function send(): void {};
    }
    
    class Order
    {
         // тут будет любой, но обязан реализовать SenderInterface
         private $sender;
    
         public function __constuctor(SenderInterface $sender) {
              $this->sender = $sender;
         }
     
         public function save(): void 
        {
            // какой в приватном поле сидит, тот и отправит, 
            // а кто -- текущему объекту все равно, это есть инверсия зависимости 
            // и принцип единственной ответственности, данный класс не отправляет, а поручает
            $this->sender->send();
        }
    }
    
    class MailSender implement SenderInterface
    {
         public function send(): void
         {
               // тут отправка почтой
         }
    }
    
    class TelegramSender implement SenderInterface
    {
         public function send(): void
         {
               // тут отправка телегой
         }
    }
    
    
    // Пример полиморфной работы Order
    $order = new Order(new TelegramSender());
    $order->save(); // тут отправка телеграмом
    
    $order = new Order(new MailSender());
    $order->save(); // тут отправка mail


    Как видите, мы можем добавлять новые сендеры, в них что-то делать, а с ордером будем работать как прежде $order->save() , и вообще его код не трогать

    Дополнение
    Интерфейс есть у любого класса (публичны/приватный), интерфейс наследуется у абстрактного/обычного класса ребенком (кроме того, что наследует поведение), почему полиморфизм иногда (на самом деле ооочень часто) объясняют именно на наследовании одного класса и множественной реализации в виде детей. На самом деле все дело в этом самом интерфейсе.
    Ответ написан
    1 комментарий
  • Как логично и структурно именовать переменные?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Подскажите, более опытные коллеги, как вы именуете переменные?

    Максимально близко к естественному языку. А так же желательно с учетом рекомендаций к стандартам именований принятых в конкретном яп, $homepage_product_name == > $nameOfProductOnHomepage, хотя зачем там хоумпэйдж и чем отличается от не на хоумпэйдж - загадка.
    Ответ написан
    3 комментария
  • Как логично и структурно именовать переменные?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    В английском языке существительные в начале превращаются в прилагательные, а в конце - существительное, к которому они относятся.
    Сравните: "stone wall" (каменная стена) и "wall stone" (камень из стены).

    То есть первым делом нужно определиться с главным существительным, то есть ЧТО имеется в виду. Если это имя, то название переменной должно оканчиваться на _name (или Name в зависимости от стиля).

    Далее, если не придираться к правилам, то последовательность прилагательных лучше делать так: чем важнее, тем ближе к существительному.
    Шаг первый: product_name
    Шаг второй: homepage_product_name (при этом вам должно быть очевидно, что не home_page)

    Далее, ничего лишнего быть не должно, и должно максимально точно отражать суть. Например, настройка, говорящая о том, что уведомления можно посылать только если приложение неактивно.
    Не правильно: notify_if_inactive (вообще не понятно, не логично)
    Правильно: is_notify_if_inactive_only
    Приставка is_ в данном случае является соглашением в нашей команде, указывающем, что это булева переменная, можно также юзать b_ например для той же цели. Или, скажем, если это константа или меняется очень редко, можно записать капсом или добавить приставку c_

    Вообще дальше уже начинаются тонкости и вкусовщина. Основные принципы изложены выше - это четкий порядок построения и соответствие сути.
    Ответ написан
    Комментировать
  • Узко vs Широконаправленный разработчик?

    Adamos
    @Adamos
    Узконаправленный разработчик - это человек, который досконально знает нюансы своей ниши и имеет кучу опыта в тех вопросах, которые в них возникают.
    Широконаправленный разработчик - это человек, который попробовал многое и успешно воплотил проекты в нескольких разных нишах.
    А тот, кто пролеживал бока, листая Танненбаума и Дейкстру - это вообще не разработчик, и нанимать его никто не будет по той простой причине, что опыта у него нет, и оплачивать время, пока он будет его набирать, набивая свои нубские шишки, никто не разбежался.

    Книги - это прекрасно. Но в разработчиках ценят не умение проходить тестирование, а реальный опыт и приобретенные навыки. Даже если идиоты-эйчары организуют наем поперек этой логики.
    Ответ написан
    Комментировать
  • Как сделать редирект в каталог с корня сайта?

    prrrrrrr
    @prrrrrrr
    Верстаю сразу на PHP.
    $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
    
    if ($lang === "ru") { header("Location: /ru"); }
    elseif ($lang === "en") { header("Location: /en"); }
    elseif ($lang === "de") { header("Location: /de"); }
    Ответ написан
    6 комментариев
  • Для чего нужная такого вида запись создания экземпляра класса?

    Konata69lol
    @Konata69lol
    backend developer (php/go)
    Создать сервисный класс и тут же вызвать его метод.
    Иногда удобно, если он не используется по всему классу, а только в одном месте.
    В противном случае его инжектят в конструктор
    Ответ написан
    4 комментария
  • Правильно ли я понимаю суть Интерфейсов в ООП?

    @stictt
    просто рак
    Не скажу за тонкости PHP , но в целом направление верное. Прежде всего интерфейс выполняет 2 роли, это интерфейс взаимодействия класса и апкастинг. Интерфейс взаимодействия это все публичные члены и методы класса в своей совокупности к которым можно обратиться, интерфейс структуризирует для всех классов один интерфейс взаимодействия, как человек выше говорил, по договору. Но это только малая часть преимуществ, основная сила это Апкаст, приведение от частного к общему. Грубо говоря вы назначили реализацию интерфейса классу, потом вы можете привести класс к интерфейсу, и обьявить тип интерфейса присвоив в переменную любой класс который будет иметь реализацию интерфейса, таким образом мы получаем очень динамическую систему которая может менять реализацию, манеру поведения, и много чего еще, без изменения в коде, по одному только интерфейсу взаимодействия. У вас 100500 классов, а обращаться вы к ним можете абсолютно одинаково, вам не нужно прописывать для каждого типа. для каждого другого обьекта вызов сугубо его методов.
    Ответ написан
    Комментировать
  • Как сделать простой php маршрутизатор (роутер)?

    devg
    @devg
    I am Yenior software developer
    Очень простой роутер, не без недостатков, но довольно быстрый и легко использовать, дописывать под себя.

    <?php
    /**
     * Простой роутер
     * @devg
     */
    final class RouterLite {
    
      public static $routes = array();
      private static $params = array();
      public static $requestedUrl = '';
    
      /**
       * Добавить маршрут
       */
      public static function addRoute($route, $destination=null) {
        if ($destination != null && !is_array($route)) {
          $route = array($route => $destination);
        }
        self::$routes = array_merge(self::$routes, $route);
      }
    
      /**
       * Разделить переданный URL на компоненты
       */
      public static function splitUrl($url) {
        return preg_split('/\//', $url, -1, PREG_SPLIT_NO_EMPTY);
      }
      
      /**
       * Текущий обработанный URL
       */    
      public static function getCurrentUrl() {
        return (self::$requestedUrl?:'/');
      }
    
      /**
       * Обработка переданного URL
       */
      public static function dispatch($requestedUrl = null) {
    
          // Если URL не передан, берем его из REQUEST_URI
          if ($requestedUrl === null) {
            $uri = reset(explode('?', $_SERVER["REQUEST_URI"]));
            $requestedUrl = urldecode(rtrim($uri, '/'));
          }
    
          self::$requestedUrl = $requestedUrl;
    
          // если URL и маршрут полностью совпадают
          if (isset(self::$routes[$requestedUrl])) {
            self::$params = self::splitUrl(self::$routes[$requestedUrl]);
            return self::executeAction();
          }
    
          foreach (self::$routes as $route => $uri) {
            // Заменяем wildcards на рег. выражения
            if (strpos($route, ':') !== false) {
              $route = str_replace(':any', '(.+)', str_replace(':num', '([0-9]+)', $route));
            }
    
            if (preg_match('#^'.$route.'$#', $requestedUrl)) {
              if (strpos($uri, '$') !== false && strpos($route, '(') !== false) {
                $uri = preg_replace('#^'.$route.'$#', $uri, $requestedUrl);
              }
              self::$params = self::splitUrl($uri);
                
              break; // URL обработан!
            }
          } 
          return self::executeAction();
      } 
    
     /**
       * Запуск соответствующего действия/экшена/метода контроллера
       */
      public static function executeAction() {
        $controller = isset(self::$params[0]) ? self::$params[0]: 'DefaultController';
        $action = isset(self::$params[1]) ? self::$params[1]: 'default_method';
        $params = array_slice(self::$params, 2);
    
        return call_user_func_array(array($controller, $action), $params);
      }
    
    }
    ?>


    Пример использования:
    <?php
    // маршруты (можно хранить в конфиге приложения)
    // можно использовать wildcards (подстановки):
    // :any - любое цифробуквенное сочетание
    // :num - только цифры
    // в результирующее выражение записываются как $1, $2 и т.д. по порядку
    
    $routes = array(
      // 'url' => 'контроллер/действие/параметр1/параметр2/параметр3'
      '/' => 'MainController/index', // главная страница
      '/contacts' => 'MainController/contacts', // страница контактов
      '/blog' => 'BlogController/index', // список постов блога
      '/blog/:num' => 'BlogController/viewPost/$1' // просмотр отдельного поста, например, /blog/123
      '/blog/:any/:num' => 'BlogController/$1/$2' // действия над постом, например, /blog/edit/123 или /blog/dеlete/123
      '/:any' => 'MainController/anyAction' // все остальные запросы обрабатываются здесь
    ));
    
    // добавляем все маршруты за раз
    RouterLite::addRoute($routes);
    
    // а можно добавлять по одному
    RouterLite::addRoute('/about', 'MainController/about');
    
    // непосредственно запуск обработки
    RouterLite::dispatch();
    ?>


    UPDATE (07.08.2017):
    Дальнейшее развитие данного роутера см. в проекте Litero (https://github.com/bit55/litero)
    Ответ написан
    1 комментарий
  • Обязательно ли читать книгу по языку/технологии что бы быть тру и продвинутым кодером?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Вы не найдёте ни одного авторитетного программиста с мировой известностью, который бы утверждал, что курсы и видео-уроки лучше книг. Обычно это утверждают либо профаны, оправдывающие своё нежелание читать, либо авторы курсов, делающие деньги на лентяях и глупцах. И я лично за 18 лет в отрасли встретил множество программистов, но ни одного хорошего, выучившегося по курсам и видео-урокам.

    Видеокурс может запилить любой дурак. Чтобы написать книгу, нужно иметь авторитет достаточный для издательства. Кроме того, текст пройдёт редактуру нескольких профессионалов. Поэтому знания в книгах качественные и систематизированные. Для начинающего это очень важные качества.

    К тому же, после достижения профессионального уровня достаточного чтобы называться специалистом, вы обнаружите, что необходимые на этом уровне знания можно почерпнуть только из документации. То есть всё равно придётся читать. Много и часто.

    Наконец, постоянная практика чтения неизбежно приводит к увеличению скорости чтения. И наступает момент когда прочитать учебник будет в 10 и более раз быстрее, чем просмотреть видеокурсы по той же теме и в том же объёме.

    Кроме того, чтение развивает абстрактное мышление - основной инструмент разработчика.
    Ответ написан
    16 комментариев
  • Почему видеоуроки - это зло?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    не важно каким образом ты что-то изучаешь, главное, что в итоге ты получишь знания

    Кроме достижения цели есть еще такой фактор, как время. А время, как известно - деньги. Объемы и скорость потребления текстовой информации всегда выше, чем видео. Текст - это:
    • Возможность бегло просматривать, на автомате фильтруя воду
    • Возможность пользоваться поиском и гиперссылками
    • Возможность копипастить
    • Зачастую более полная информация
    • Чем больше читаете, тем быстрее читаете, тем больше читаете, тем быстрее читаете....
    • + В наших краях читать на английском большинству проще, чем слушать

    Как вы читаете подобную литературу и как мне не умирать после каждой страницы?

    Книги и статьи по разработке, маны и документации - это тексты, которые читать последовательно от корки до корки долго, скучно и неэффективно. Гораздо лучше быстро скользить взглядом, останавливаясь на важных моментах. А если объем большой - то сразу пролистывать все, а потом "спускаться на уровень ниже" за подробностями по тому или иному вопросу. Так книжка на 700-800 страниц может пролистываться за день, а затем при необходимости можно точечно просматривать темы, которые нужны на данный момент. Вести записи в тетрадях для запоминания также почти всегда неэффективно, лучше сразу практиковаться. Что нужно - само запомнится, а что не нужно - просто знайте где почитать, на случай если оно вдруг понадобится.
    Ответ написан
    Комментировать
  • Как загрузить данные из файла в массив php?

    irishmann
    @irishmann
    Научись пользоваться дебаггером
    Функция file() читает файл построчно в массив
    Ответ написан
    3 комментария
  • Как сохранить результат парсинга в MySQL.?

    php666
    @php666
    PHP-макака
    Я чуть не поперхнулся от такого задания...
    Какой-то наркоман его придумал.
    НЕ ХОДИ К НИМ РАБОТАТЬ, слышишь? Они - идиоты.
    И задания у них крайне идиотские.

    Образно представляю что должно получиться, но как это реализовать не очень ясно
    Мне тоже. Идиотские задачи вообще очень тяжело поддаются анализу.
    Ответ написан
  • Как понять структуру классов (объектов) в CMS?

    Adamos
    @Adamos
    Важно правильно определить цель.
    Вам не нужно досконально знать, как написана ОпенКарт.
    Вам всего лишь нужно разобраться, как с ней работать.
    А для этого у того кода, который используют многие, находятся и мануалы, и статьи, и образцы, и готовые хаутушки.
    Ответ написан
    6 комментариев
  • Как реализовать редактирование записи из БД при клике на ссылку?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    обернуть весь блок формой, сделать инпуты с данными, сделать их hidden, по кнопке скриптом показать инпуты, по другой вернуть все состояния обратно.
    Ответ написан
    2 комментария