Ответы пользователя по тегу PHP
  • Код внутри. Как засунуть include в переменную?

    copist
    @copist
    Empower people to give
    Вариант 1.
    <? $siteMenu = include($_SERVER['DOCUMENT_ROOT'].'/core/modules/menu.php'); ?>

    содержимое файла menu.php должно быть таким
    <?php
    return array(
        "пункт меню 1",
        "пункт меню 2",
        "пункт меню 3",
    );


    Вариант 2.
    <?php
    function getMenu()
    {
      ob_start();
      include $_SERVER['DOCUMENT_ROOT'].'/core/modules/menu.php';
      return ob_get_clean();
    }
    
    $siteMenu = getMenu();

    содержимое файла menu.php должно быть таким
    <ul><li>пункт меню 1</li><li>пункт меню 2</li><li>пункт меню 3</li></ul>
    Ответ написан
    4 комментария
  • Какие преимущества хранения сессий в бд?

    copist
    @copist
    Empower people to give
    Сессию в базе хранят на тот случай, если там есть что-то ценное.
    Например, есть конструктор сайтов или социальная сеть. И пользователь может кое-что сделать ещё до регистрации, например, создать пост или профиль свой заполнить. Можно все его временные данные сериализовать и поместить в базу, чаще всего JSON в NoSQL.
    В обычную сессию тоже можно сохранить, но обычно пространство для хранения сессий регулярно чистят и тогда данные потеряются.
    Сохранять в базу стоит только тогда, когда пользователь сделал что-то. Для каждого пользователя выделять место в базе бессмысленно.
    Когда пользователь авторизуется, временные данные переносят на постоянное место хранения.
    Регулярно область сессий неавторизованных пользователей чистят, но гуманно, то есть не очень активно, с большим интервалом хранения.

    Я обычно с другим сталкивался - данные из базы выгружают в сессию, чтобы меньше нагружать базу.
    Вот схема: https://toster.ru/answer?answer_id=645494
    Ответ написан
  • Есть ли такой паттерн?

    copist
    @copist
    Empower people to give
    Нельзя вызвать __destruct объекта. Он вызывается автоматически, когда сборщик мусора определяет, что этот объект больше никому не нужен (не осталось ссылок на него)

    Если ты скажешь: "Но ...?", отвечу: "А что делать тем, кто этим объектом уже пользуется?"
    class SelfDestructible
    {
        public $myname;
        function __construct($myname)
        {
            $this->myname = $myname;
        }
    }
    
    $a = new SelfDestructible('#1');
    // Эта конструция буквально означает следующее: 
    // 1. выделить область памяти под объект '#1'
    // 2. поместить в переменную $a адрес этой области памяти
    // Иначе говоря, в переменной $a хранится указатель на объект
    
    $b = new SelfDestructible('#2');
    // Согласно твоей логике, тут должна была бы освободиться память, выделенная ранее под объект '#1'
    // но как же поступить с переменной $a, которая всё ещё хранит адрес области памяти этого объекта
    // И через переменную $a можно обратиться к той области памяти.
    // То есть вломиться в склеп, где лежат останки безвременно погибшего объекта '#1' и бесчестно
    // надругаться над ним
    // Ни один язык такое кощунство и вандализм не позволит


    P.S. поправка под уточнёный вопрос

    class SingleSingleton
    {
        /**
         * приватный - чтобы никто не делал new SingleSingleton
         */
        private function __construct()
        {
        }
    
        /**
         * @return static
         */
        public static function getInstance()
        {
            static $instatiated; // признак, что ещё не делали экземпляр класса
            if (is_null($instatiated)) // если ещё не делали экземпляр класса
            {
                $instatiated = true; // пометить, что теперь сделали
                return new SingleSingleton; // вернуть новый объектт
                // метод getInstance может делать new SingleSingleton потому что находится в том же классе
            }
            else // уже был создан объект
            {
                return null; // вернуть ничего
            }
        }
    }
    
    // первый получит объект
    $a = SingleSingleton::getInstance();
    var_dump($a); // -> object(SingleSingleton)#1 {}
    
    // второй получит ничего
    $b = SingleSingleton::getInstance();
    var_dump($b); // -> NULL
    
    // а сделать new SingleSingleton нельзя
    $c = new SingleSingleton; // -> PHP Fatal error
    Ответ написан
  • Как мне сортировать поля по моим правилам?

    copist
    @copist
    Empower people to give
    Сделай два запроса и соедини в PHP. Так будет проще.
    Ответ написан
    Комментировать
  • Phpstorm конфликты классов как быть?

    copist
    @copist
    Empower people to give
    PHPStorm не инклудит, а телает typehint
    Ну и пусть жалуется, раз они у тебя дублируются.

    А отсутствующий класс надо исправить - либо создать класс, либо удалить упоминания про него
    Ответ написан
    Комментировать
  • Наставник, где мне тебя найти?

    copist
    @copist
    Empower people to give
    Возможно, ответ не актуален автору.
    Для тех, кто попал с поиска, просто оставлю это здесь : webmentor.pro
    Ответ написан
    Комментировать
  • Новостной сайт с публичным api?

    copist
    @copist
    Empower people to give
    Любой RSS. Выдаётся в XML. Парсить легко. Любой новостной ресурс.
    habrahabr.ru/rss/interesting
    lenta.ru/rss
    Ответ написан
  • Стоит ли отходить от нормализации бд, чтобы улучшить производительность?

    copist
    @copist
    Empower people to give
    Можно завести ещё одну таблицу - список тех, кто поменял что-то совсем недавно и для него надо обновить вычисленное поле. Проходить только по ней. Сократит время обновления.

    Или перевычислять это поле по факту изменений, но асинхронно, через очереди.
    Ответ написан
  • Можете объяснить, чем полезна буферизация?

    copist
    @copist
    Empower people to give
    Гарантия того, что заголовки HTTP отправятся раньше, чем содержимое.
    Ответ написан
    Комментировать
  • Как решить проблему после отправки POST?

    copist
    @copist
    Empower people to give
    Если надо остаться на той же странице
    <?php
    if (/* login success */) {
       header("HTTP/1.1 205 Reset Сontent");
    }

    Можно никуда не редиректить. Браузер забудет, что отправлял данные методом POST. Если перегрузить страницу, сообщений "Надо повторно отправить форму..." не появится.

    Если надо перейти на другую страницу, но чтобы не появлялось "Чтобы отобразить эту страницу, XXX должен отправить информацию..." когда он в браузере кнопку "Вернуться" нажмёт
    <?php
    if (/* login success */) {
       header( 'Location: /* new location*/', true, 205);
    }
    Ответ написан
  • Каковы Возрастные ограничения в программировании?

    copist
    @copist
    Empower people to give
    Может что посоветуете для начала карьеры, так как сейчас работаю в совершенно другой сфере в жестком графике и чисто физически времени и сил не хватает на то чтобы быстрее вникнуть.

    А кто обещал быстро?
    Ответ написан
    Комментировать
  • CURL Почему сервер возвращает неполный ответ?

    copist
    @copist
    Empower people to give
    nginx ? Проверьте права на запись в /var/lib/nginx/fastcgi/
    Ответ написан
    Комментировать
  • Как проверить размер загружаемых файлов до загрузки на сервер?

    copist
    @copist
    Empower people to give
    Можно прочитать файл, не загружая на сервер
    Вот пример codepen.io/copist/pen/VvmLbZ - выбери файл в формате SVG и он сразу будет отображён. POST или AJAX не используются.

    Есть специальные библиотеки на JS, которые занимаются валидацией файлов на стороне браузера: расширение, размер в байтах, размер изображений в пикселах. У меня вот проверяется что выбран именно файл, содержащий разметку в формате SVG.

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

    copist
    @copist
    Empower people to give
    Если под стилем подразумевается рамка вокруг картинки, то легко

    .icon {
        border: 1px solid red;
    }


    А если нужен доступ к отдельным линиям, то не используй embed, a вставляй сразу в HTML.
    Вот пример: меняется видимость и цвет элементов codepen.io/copist/pen/WvVRRL
    Ответ написан
    Комментировать
  • Почему $_SERVER['REQUEST_URI'] захватывает лишние url-ы?

    copist
    @copist
    Empower people to give
    В правилах веб-сервера перенаправляйте запросы к статике (CSS и картинки) в PHP. Просто отдавайте 404 Page Not Found.
    К примеру, для веб-сервера nginx, условно:

    # Не перенаправлять запросы про несуществующие статические файлы в PHP
    location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|woff|ttf|eot|svg)$ {
        root /var/www/applicaion; # путь к приложению
        access_log off; # логи не писать
        try_files $uri =404; # не вызывать PHP
    }
    Ответ написан
    Комментировать
  • Как правильно реализовать десктоп клиента для веб приложения?

    copist
    @copist
    Empower people to give
    1. Сокеты для постоянного обмена, если нужно оперативно данные с сервера получать. Можно и оправлять.
    AJAX если данные запрашиваются по мере необходимости.
    2. Используй SSL и не беспокойся за сеансовый ключ
    Ответ написан
    Комментировать
  • Почтовый клиент на PHP, напрямую или через базу данных?

    copist
    @copist
    Empower people to give
    только изредка в фоновом режиме проверяют не пришло ли новое письмо

    да, так
    Ответ написан
    1 комментарий
  • Как защитить денежный баланс на сайте от накрутки?

    copist
    @copist
    Empower people to give
    Пользуйтесь ключами RSA, у каждого пользователя своя пара ключей. Один (публичный) передаётся на сервер, другой (приватный) остаётся у пользователя. Когда делается транзакция, например покупка, то на сервер должна поступать информация:
    1. идентификатор покупателя
    2. номер счёта покупателя
    3. идентификатор продавца
    4. номер счёта продавца
    5. идентификатор покупки
    6. валюта
    7. точная сумма покупки
    8. точное время транзации в таймзоне UTC

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

    Чтобы выполнить транзакцию (покупку), нужно проверить, хватает ли средств на балансе пользователя-покупателя. Для этого нужно изъять из базы все транзакции пользователя-покупателя, по каждой транзакции провести проверку отпечатка и суммировать те, у которых отпечаток корректный.

    Проверяйте время транзакций. У каждого покупателя все транзакции должны быть строго хронологическими. Не должно быть чтобы покупка N+1 была ДО покупки N.

    Это вычисляется долго. Чтобы ускорить вычисление остатка, можно ввести специальный тип транзакции "состояние на начало месяца". Его должны выполнять сторонний доверенный сервер, имеющий свою специальную пару ключей. Тогда текущий баланс = последний остаток на начало месяца + все поступления - все оплаты. Вычисляется значительно быстрее.

    Если злоумышленник взломает базу данных, то внесёние записей будет чрезывычайно затруднительным, потому что подделать отпечаток транзакции будет невозможно. Слабое звено - можно просто выгрузить базу или таблицу в файл и затем дропнуть таблицу или базу и шантажировать вас потерянными данными. Чтобы исключить такое, запретите пользователям (не покупателям, а тем, которые подключаются к базе) делать DROP TABLE/DATABASE. Ещё делайте резервные копии. Ещё держите зеркало базы данных.

    Всё что я описал, будет бесполезно, если злоумышленник заменит исходный код платёжного сервера, так как он сможет просто вырубить все проверки на отпечатки. Поэтому платёжный сервер не должен быть скриптовым. То есть не PHP, node, Python, Ruby. Это должен быть компилируемый код. С цифровой подписью. Сервер не должен исполнять приложения с отсутствующей или неправильной цифровой подписью.

    Но это не мешает подменить список доверенных центров сертификации на сервере, чтобы запустить поддельное приложение вместо платёжного сервера. Поэтому на стороне СУБД нужно реализовать механизм, который не даёт подключиться к базе любому приложению. Это приложение должно иметь специальный механизм доступа. Ограничение по IP, специальные заголовки, особенная сессия. Значит это не MySQL и, скорее всего, не PostgreSQL.

    Ещё о каком-нибудь головняке рассказать или уже достаточно?

    Специалисты из WebMoney, PayPal, Yandex.Деньги и онлайн-банков сейчас не скрывая улыбки смотрят на мой алгоритм. Привет вам всем, друзья!

    Относительно реализации на PHP. Два сервера с запросами через AJAX не сделают сервер надёжнее, потому что всё можно подделать в браузере.

    Нужно предотвратить доступ пользователя к серверу. В Интернет огромное количество статей на эту тему. Я боюсь, что полный список средств предотвращения доступа я просто не вспомню. В любом случае, способов взлома больше, чем методов защиты в PHP.

    Вот списочек способов проникнуть на сервер:
    • Через уязвимости серверных компонентов;
    • Через уязвимости в веб-окружении сервера;
    • Через удаленное выполнение произвольного кода;
    • Через наличие переполнений;
    • Через инъекции (внедрение кода) (например, SQL Injection);
    • Через обход системы аутентификации веб-ресурса;
    • Через XSS / CSRF;
    • Через перехват привилегированных аккаунтов (или сессии таких аккаунтов);
    • Через Remote File Inclusion / Local File Inclusion;
    • Через компоненты CMS, CMF и фреймворков с известными уязвимостями;
    • Через перенаправление на другие сайты c помощью открытых редиректов;
    • Через сканирование директорий и файлов (поиск дампов, данных про git, svn);
    • Через подбор паролей.


    И вот списочек способов снижения вероятности проникновения и нанесения непоправимого ущерба:

    Состояние серверов
    • Держи сервера в актуальном состоянии, следи за найденными уязвимостями, обновляй серверные приложения
    • Делай бакапы файлов и баз данных, держи зеркальную базу данных; в случае беды - используй копию
    • Используй виртуальные машины, делай периодически снимки, а в случае взлома восстанавливай машины из снимков
    • Больше не вспомню. Держи админа под рукой.


    Доступ к серверам
    • Не подключайся от имени пользователя root, заведи другого.
    • Установи на всех пользователей длинный пароль.
    • Запрети всем пользователям делать sudo. Можно разрешить делать некоторые отдельные операции, например, nginx reload.
    • Для подключения к серверам пользуйтя SSH или SFTP, авторизация по ключам
    • Смени порты сервисов SSH и SFTP
    • Установи ограничение на список IP, с которых можно подключиться к серверу. Сделай себе белый IP адрес.


    Внутренние сервисы
    • Если всё приложение на одном сервисе, то все внутренние службы (mysql, memcached, raddis, rabbit) должны слушать только интерфейс 127.0.0.1. ( habrahabr.ru/post/212265 )
    • Если приложение включает несколько серверов (отдельно база, отдельно PHP), то есть представляет собой кластер, то службы должны слушать только те IP, которые относятся к кластеру.
    • Смени стандартные порты всех сервисов
    • Пользователю UNIX от которого работает PHP-FPM / NGINX/ APACHE, должны быть открыты для записи только несколько директорий (upload, логи, временные файлы), а для исполнения - вообще ничего нельзя.
    • Пользователю базы данных не должны быть доступны деструктивные и небезопасные операции (DROP/ALTER/CREATE PROCEDURE), может быть даже для INSERT/UPDATE/DELETE в данных по финансам использовать другой аккант в базе данных


    Приложение PHP
    • Защищай сайт с помощью SSL
    • Используй дополнительный платёжный пароль, ограничивай количество попыток оплаты с неверным паролем
    • Используй server side http cookie, короткие сессии с привязкой ключа сесии к IP и UserAgent клиента
    • Все запросы к базу должны быть только с использованием связываемых параметров, никаких конкатенаций запроса с параметрами (Внедрение SQL-кода, SQL injection, php.net/manual/ru/security.database.sql-injection.php и другое по фразе SQL injection )
    • Не доверяй проверкам данных на стороне клиента. Да, они ускоряют работу, но их можно легко подделать. Поэтому все проверки дублируй в коде на сервере.
    • Не доверяй данным пользователя: фильтруй строки, отрезай теги, укорачивай до допустимой длины, приводи к числам все числа (wikipedia: CSS, Cross Site Scripting — «межсайтовы..., XSS для новичков, Яндекс: XSS-атаки и другое по фразе "XSS")
    • Все запросы на сервер должны сопровождаться токеном безопасности ( https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D... https://learn.javascript.ru/csrf habrahabr.ru/post/235247 и другое по фразе "CSRF" )
    • Нигде не делай авто-редирект на страницу, указанную в параметрах запроса - так обычно делают, чтобы после логина вернуться туда, откуда была вызвана форма логина
    • Про содержимое транзакций уже писал, не знаю что из этого тебе пригодится
    Ответ написан
    4 комментария
  • Какое посоветуете легкое IDE для PHP под Linux?

    copist
    @copist
    Empower people to give
    phpStorm - слишком монструозный и навязчивый, как будто для проектирования самолета;

    Не стесняйся признаться, что ты всегда мечтал сконструировать ракету. Слезть с phpStorm будет сложно, особенно после взлёта твоей ракеты.
    Ответ написан
    Комментировать
  • VOLТ, Phalcon, XSS как исправить?

    copist
    @copist
    Empower people to give
    Как инициируется markDown ? Что это?

    А так работает?

    {% set post_message = post.message|e %} {# не портить внутренности объекта post #}
    
    <div class="post-text">
        {{ markDown.parse(post_message ) }}
    </div>
    Ответ написан
    3 комментария