• Выдает ошибку при выводе записей из бд?

    @unity_ultra_hardcore
    Отвратительный код, но конкретно в этом случае переменную $db надо объявить глобальной:
    <?php
    
    require('database.php');
    
    $db = new SafeMySQL();
    
    class Add
    {
        public function showphotos() {
            global $db;
            $data = $db->getAll("SELECT * FROM photos");
            echo json_encode($data);
        }
    }
    
    $test = new Add();
    $test->showphotos();

    А лучше сделать явную зависимость класса Add от подключения:

    <?php
    
    require('database.php');
    
    class Add
    {
        protected $db;
    
        public function __construct(SafeMySQL $db)
        {
            $this->db = $db;
        }
    
        public function showphotos() {
            $data = $this->db->getAll("SELECT * FROM photos");
            echo json_encode($data);
        }
    }
    $db = new SafeMySQL();
    $test = new Add($db);
    $test->showphotos();
    Ответ написан
    Комментировать
  • Почему не выводится дата?

    @unity_ultra_hardcore
    У вас там ошибка: вы обращаетесь не к каждому span.dateOnline, а к их коллекции. Нужно в цикле обратиться к каждому элементу коллекции примерно вот так:

    var elems = document.getElementsByClassName('dateOnline');
    
    for (var i = 0; i < elems.length; i++) {
    	elems[i].innerHTML = '<span>' + time.getDate() + " " + month[time.getMonth()] + '</span>';
    }
    Ответ написан
    Комментировать
  • Использование нескольких ВК-приложений на PHP API – как не плодить условия на тип приложения?

    @unity_ultra_hardcore
    1. Хранить в базе ещё и тип и плодить два условие типа.

    Да. Хранить рядом с токеном не только срок его действия, соцсеть из которой он получен (в случае, если все токены в одной таблице) и его тип: website/standalone
    Эту проверку можно инкапсулировать внутр вашего $social:
    If ($social->canPostOnWall($entity) {
        $social->postOnWall($entity);
    }


    Думаю, что в методе canPostOnWall те провайдеры, что не умеют постить оффлайн, должны просто возвращать false. А VK должен проверить наличие в хранилище токена с этим user_id, с expire > now() и с type = 'standalone' и пытаться запостить сообщение на стене, если подходящий токен нашёлся.
    Ну, это если я верно понял вашу архитектуру.
    Ответ написан
    3 комментария
  • В каком режиме работает php?

    @unity_ultra_hardcore
    php_sapi_name вернёт 'fpm-fcgi' в случае fpm и 'cli' в случае cli.
    Ответ написан
  • Чем вы пользуетесь, sprintf или оператором(точкой) для внедрения параметров в строку в PHP?

    @unity_ultra_hardcore
    если подстановки идут в середине строки или их больше одной - использую sprintf.
    Вот такой код мне совсем не нравится (пример придуман из головы):
    $str = 'select `field` from `' . $table . '` where id = "' . $val . '"';

    Особенно, мне не нравятся сочетания кавычек перед/после $table
    Так куда лучше:
    $str = sprintf(
        "select `%s` from `%s` where `id` = '%d'",
        $field,
        $table,
        $id
    );

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

    @unity_ultra_hardcore
    Лучше папку именовать не как id, а как какая-нибудь простая хеш-функция от этого id. Причем, не класть всё на один уровень, а распределить их на 2-3. Ниже пример для статьи с id=123
    md5(123) = 202cb962ac59075b964b07152d234b70
    берем первый символ хеша - 2, создаем папку "2" в /uploads/images
    берем второй символ хеша - 0, создаем папку "0" в /uploads/images/2
    создаем папку "202cb962ac59075b964b07152d234b70" в /uploads/images/2/0/
    кладём в /uploads/images/2/0/202cb962ac59075b964b07152d234b70 нужные файлы

    Плюсом такого рещения будет то, что из-за хеш-функции папок будет фиксированное количество и файлы по ним будут относительно равномерно размазаны. Если файлов будет очень много, можно добавить ещё один уровень. Путь этот вычислить программно будет не сложно, если метод его вычисления будет находиться в одном месте.
    Ответ написан
    7 комментариев
  • Как правильно определить браузер пользователя?

    @unity_ultra_hardcore
    Тем не менее, get_browser - это лучший способ, дающий максимально релевантную и удобную информацию
    Ответ написан
  • Как правильно хранить в базе данные о авторизации юзера через социальную сеть?

    @unity_ultra_hardcore
    У нас используется следующая схема таблиц:
    Table "public.social_account"
       Column    |              Type              | Modifiers
    -------------+--------------------------------+-----------
     user_id     | integer                        | not null
     network     | character varying(255)         | not null
     external_id | character varying(255)         | not null
     created_at  | timestamp(0) without time zone | not null
     updated_at  | timestamp(0) without time zone | not null
     id          | uuid                           | not null
    Indexes:
        "social_account_pkey" PRIMARY KEY, btree (id)
        "unique_social_account" UNIQUE, btree (network, external_id)
        "idx_f24d8339a76ed395" btree (user_id)
    Foreign-key constraints:
        "fk_f24d8339a76ed395" FOREIGN KEY (user_id) REFERENCES app_user(id) ON DELETE CASCADE


    То есть для каждой привязки хранится запись, в которой содержится user_id, название соцсети (google/vk/facebook/etc) и id этой соцсети (у всех произвольный формат).
    Таким образом, когда пользователь аутентифицируется через одну из этих соцсетей, сначала ищется user_id по связке external_id + network. Если user_id найден - аутентифицируем текущего пользователя как этот user_id. Если нет, получаем от соцсети email и по нему ищем пользователя в таблице пользователей. Если нашли, то создаем запись в social_account и аутентифицируем юзера. Если не нашлось ничего (первый визит), то создаем пользователя и создаем запись в social_account.
    Ответ написан
  • Как создать проект на Symfony2 с конфигами на PHP, а не на YAML?

    @unity_ultra_hardcore
    В бандле у вас есть файл DependencyInjection/AcmeAppExtension.php.
    Если его содержимое привести примерно к такому виду, то должно получиться (правда сам я не пробовал этим заниматься).
    <?php
    
    namespace Acme\AppBundle\DependencyInjection;
    
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\Loader;
    
    /**
     * This is the class that loads and manages your bundle configuration.
     *
     * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
     * @codeCoverageIgnore
     */
    
    class AcmeAppExtension extends Extension
    {
        /**
         * {@inheritdoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {
            $configuration = new Configuration();
            $this->processConfiguration($configuration, $configs);
    
            $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__ . '/../config/'));
            $loader->load('services.php');
    
            if ($container->getParameter('kernel.environment') == 'dev') {
                $loader->load('services_dev.php');
            }
    
            if ($container->getParameter('kernel.environment') == 'test') {
                $loader->load('services_test.php');
            }
        }
    }

    P.S. я лично тоже считаю, что это большая глупость - отказываться от yml в пользу php-конфигов: это нарушает основной принцип конфигурации - ее детерминированность. В php-конфиге можно наворотить какой-то логики при вычислении того или иного параметра, что отрицательно скажется на удобстве поддержки проекта.
    Ответ написан
    Комментировать
  • Бессмысленно ли упрощать код таким способом?

    @unity_ultra_hardcore
    По-моему, велосипеды должны быть чем-то оправданы. В данном случае ничем: есть масса готовых, качественных и оттестированных библиотек ровно с таким же API. Снабженных документацией и имеющих распространение на рынке.
    Если это учебное занятие - то ок, если вы тратите деньги работодателя на написание подобного - это не ок.
    Ответ написан
    5 комментариев
  • Будет ли возможно использовать 3D-Touch в веб-дизайне?

    @unity_ultra_hardcore
    Safari 9 уже содержит апи для поддержки 3d touch, но более подробно мне сходу нагуглить не удалось, надо подождать релиз.
    Могу предположить, что в этом браузере будет пара новых событий вроде -webkit-touch-peek, -webkit-touch-pop, на которые можно будет вешать собственные обработчики.
    Ответ написан
    Комментировать
  • Как проверить, что запрос от localhost?

    @unity_ultra_hardcore
    Вот так это делает symfony, думаю, что есть смысл прислушаться:
    // This check prevents access to debug front controllers that are deployed by accident to production servers.
    // Feel free to remove this, extend it, or make something more sophisticated.
    if (isset($_SERVER['HTTP_CLIENT_IP'])
        || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
        || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
    ) {
        header('HTTP/1.0 403 Forbidden');
        exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
    }
    Ответ написан
  • Как запретить загрузку iframe на html-странице?

    @unity_ultra_hardcore
    Если что, современное и стандартное решение являет собой серверный заголовок X-FRAME-OPTIONS со значением DENY.
    Но понятно, что его с клиентской части не выставить.
    Ответ написан
    Комментировать
  • Как отправлять логи ошибок PHP на почту?

    @unity_ultra_hardcore
    Предложу немного более generic-решение: использовать Sentry.
    Ответ написан
    Комментировать
  • Как наименее русурсоемко записать массив в файл?

    @unity_ultra_hardcore
    Сильно зависит от структуры словаря. Если только строковые ключи-значения, то можно попробовать вот так его писать: https://gist.github.com/sc0rp10/0cef7c64aad392a2e799.
    Дальше советую обложиться профайлерами и самостоятельно выяснить, что выгоднее: писать построчно из большого словаря в памяти, либо один раз его сдампить в файл целиком. Ну а там уже делать вывод, что конкретно в вашем случае больше подходит.
    Лично мне кажется, что задумываться о скорости выполнения var_export + file_put_contents стоит, например, с объема данных в сотни мегабайт. В том смысле, что на более мелких объемах, эти вызовы займут крайне мало времени на фоне общего времени выполнения и смысла экономить буквально на спичках не будет.
    Но, повторюсь, все надо профилировать, а не гадать.
    Ответ написан
    Комментировать
  • Можно ли вернуть данных из команды Symfony2?

    @unity_ultra_hardcore
    Подозреваю, что лучше пересмотреть архитектуру: если заключать логику команды не в ней самой, а в сервисе (оставив в команде только получение сервиса из контейнера и вызов его метода), то такие костыли не потребуются.
    Ответ написан
    Комментировать
  • Правильный deploy Symfony2 проекта при наличии bower.json и grunt?

    @unity_ultra_hardcore
    У нас файлом /etc/project_name.yml заведует Puppet. Сам проект собирается на CI-сервере в deb-пакет (там же делается bower install, gulp build etc). В postinstall-скрипте пакета с сайтом написано что-то вроде
    cp /etc/project_name.yml /var/www/project_name/app/config/parameters.yml
    .
    То есть, нужная конфигурация уже лежит на сервере и пакет при установке просто себе ее копирует. Если нужно добавить новый параметр в файл, то сначала правится json-файл в hiera соответствующего хоста, он раскатывается на фронты, а потом уже накатывается пакет с сайтом, требующий новый ключ конфига.
    В том же postinstall выполняется скрипт проверки соответствия ключей в parameters.yml.dist и свежепоявившемся parameters.yml и если ключи расходятся, то установка считается неудачной (читай, как разработчики накосячили с конфигом, ситуация требует ручного вмешательства).
    Ключевой пойнт в том, что ни разработчики, ни CI-сервер ничего не знают про параметры боевого сервера и ограничены свой областью ответственности.
    Ну а Puppet и так "слишком много знает" об инфраструктуре, поэтому, ему этот файл доверять не страшно.
    Ответ написан
    Комментировать
  • Как добавить иконку и фон в закладки?

    @unity_ultra_hardcore
    Вам нужно API Табло, но прямо сейчас эта страница, как видите, недоступна. Можно покопаться в кеше поисковиков, Веб-архиве, попросить у разработчиков эту документацию или же просто подождать публикации актуальной версии API.
    Ну или погуглить релевантную информацию и сделать оттуда выводы.
    Например, что используется некий манифест, можно попробовать найти его на каком-нибудь сайте и "отреверсить" его формат
    Ответ написан
  • Есть ли замена крону для разовых задач?

    @unity_ultra_hardcore
    Можно реализовать отложенную очередь (delayed queue), но всё равно не обойтись без планировщика/демона, который будет проверять наличие актуальных задач и выполнять их.
    Ответ написан
    Комментировать