Задать вопрос
  • На чем написать высоконагруженный api сервер?

    @jaxel
    При больших нагрузках решающее значение имеет архитектура, а не язык. Пишите на том, что лучше знаете.
    Ответ написан
  • Проблема со скоростью загрузки страниц с коробки на symfony 2.7 или это нормально для симфони?

    @jaxel
    Для быстрой работы symfony на 5.6 надо обязательно включить opcache. Переход с апача на Nginx даёт выигрыш в скорости ещё раза в 3-4(почему, я так и не понял). Выключение xdebug тоже даёт приличный прирост скорости. В php.ini желательно установить:
    realpath_cache_size = 4M или больше

    У меня при соблюдении всех этих условий время генерации страницы 0.2-0.3 секунды в дев окружении готового приложения, и примерно 0.05-0.1 секунда - загрузка голого фреймворка.
    Ответ написан
    Комментировать
  • Чему обучать Junior'a?

    @jaxel
    Прямо на Symfony2 давать маленькие задания, с постепенным погружением в разные сферы. Начиная с элементарных вещей и усложняя задачи. Полный контроль кода, с отправкой на доработку-переделку не правильных решений с подробным объяснением, что не правильно и почему.
    Ответ написан
    2 комментария
  • Гадание по коду на собеседовании. Как проверяют кандидатов?

    @jaxel
    Я всегда считал подобное требование идиотизмом. Что можно понять по небольшому куску кода? Да ничего!
    Ладно бы ещё просили выслать исходники целиком, или большой цельный модуль, но ведь обычно просят выслать "самый изящный класс" или подобный бред. Архитектуру по нему не увидишь, умение решать сложные задачи тоже. Разве что code style посмотреть и совсем индусский говнокод выявить, но это тоже бред.
    Ответ написан
    2 комментария
  • Авторизация в Symfony2 - User account is disabled. Как починить?

    @jaxel
    Ваш класс юзера должен реализовать Symfony\Component\Security\Core\User\AdvancedUserInterface для того, чтобы работать со стандартным компонентом security.

    Согласно этому интерфейсу должен быть метод isEnabled(), возвращающий true. В противном случает возникает такая ошибка.
    Ответ написан
    Комментировать
  • Почему рынок готовых тем настолько огромен и рентабелен и каковы его перспективы?

    @jaxel
    А почему нет? Я лично уже пару десятков шаблонов купил. А я даже не компания.

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

    @jaxel
    Поржал с кода. Тут и процедурным то программированием даже не пахнет. Зачем ему вообще PHP, тоже самое можно написать на голом HTML и оно вообще будет летать:)

    PS: Думаю стоит кинуть начальнику ссылку на это обсуждение.
    Ответ написан
    Комментировать
  • Выбор PHP фреймворка?

    @jaxel
    Бери Symfony 2. Сейчас ничего лучше нет. По-началу может быть сложно, но в итоге усилия, затраченные на его изучение, принесут свои плоды.
    Ответ написан
    Комментировать
  • Какую CMS выбрать?

    @jaxel
    ИМХО, фреймворки вполне подойдут для веб-студии. Я почти все сайты клепаю на Symfony 2.

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

    Минус наверное в том, что программист для битрикса и любой другой CMS стоит намного дешевле, чем программсит на хороших фреймворках.
    Ответ написан
    5 комментариев
  • Как в Symfony 2 раскодить ( decode ) захешированный пароль ( password_hash() )?

    @jaxel
    Если у вас появилась такая необходимость, значит вы что-то делаете не так. Этот алгоритм для того и придуман, чтоб его нельзя было раскодировать.

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

    Из-за таких умельцев и приходится иметь отдельные пароли для сомнительных говносайтов.
    Ответ написан
    1 комментарий
  • Кеширование в зависимости от хостинга, возможно ли такое?

    @jaxel
    Видимо у вас в htaccess включается кеширование конструкцией вроде такого:
    <ifmodule mod_expires.c>
        <filesmatch ".(jpg|gif|png|css|js|woff)$">
                ExpiresActive on
                ExpiresDefault "access plus 30 day"
            </filesmatch>
    </ifmodule>


    Очевидно, что на одном хостнге mod_expires есть и включен, а на другом - нет.
    Ответ написан
    Комментировать
  • Можно ли устроиться программистом без оформления?

    @jaxel
    Да большинство работодателей только рады будут. Никакой белой ЗП, никаких налогов и тд.
    Ответ написан
    2 комментария
  • Как проверять данные при использовании RESTFul api в Symfony2?

    @jaxel
    А кто мешает использовать тот же валидатор, что и при работе с формами? Валидируется же доктриновская сущность, а не сама форма. Просто получаете валидатор отдельным объектом. Проверяете доктриновкий объект с описанными правилами, и всё работает точно как с формами.
    Ответ написан
    Комментировать
  • Подходит ли framework Symfony?

    @jaxel
    Отлично подходит. Есть довольно удобные бандлы для лёгкой реализации REST. https://github.com/FriendsOfSymfony/FOSRestBundle
    https://github.com/nelmio/NelmioApiDocBundle
    Ответ написан
    Комментировать
  • Почему замедляется работа скрипта?

    @jaxel
    Каким образом парсите XML? На файлах большого объёма надо использовать способы, не загружающие файл в память. Например через XMLReader.

    Как происходит добавление в базу? Доктриной? Если да, то надо разбивать добавление на небольшие пачки. Через каждые 100-200 $em->persist нужно делать $em->flush() и удалять сущности из списка управляемых $em->getUnitOfWork()->clear()

    Ещё надо учесть, что в dev окружении каждый запрос профилируется, и при больших объёмах данных это даёт многократное замедление. Надо или делать запросы в prod окружении, или отключить профилирование:
    $this->em->getConnection()->getConfiguration()->setSQLLogger(null);
    
            foreach ($this->em->getEventManager()->getListeners() as $event => $listeners) {
                foreach ($listeners as $listener) {
                    $this->em->getEventManager()->removeEventListener($event, $listener);
                }
            }
    Ответ написан
    5 комментариев
  • Как настроить кэширование изображений в PHP и ZF2?

    @jaxel
    Проще всего это сделать через .htaaccess

    <ifmodule mod_expires.c>
        <filesmatch ".(jpg|jpeg|gif|png|css|js|woff)$">
                ExpiresActive on
                ExpiresDefault "access plus 30 day"
            </filesmatch>
    </ifmodule>


    mod_expires должен быть установлен и включен
    Ответ написан
    Комментировать
  • Как подключить изображения для mcelfinder в symfony2?

    @jaxel
    Используйте опцию cssrewrite
    {% stylesheets '@FMElfinderBundle/Resources/public/css/*' filter='cssrewrite' %}
        <link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
    {% endstylesheets %}

    Или просто подключите стили без ассетика.

    Ресурсы в web установлены?
    php app/console assets:install --symlink
    Ответ написан
    Комментировать
  • При редактировании коллекции сущностей не сохраняются новые сущности - почему?

    @jaxel
    Ох, ну и накуролесили вы тут. Как оно вощбще работает?))

    Если делать вашим методом, то сущность Test должна выглядеть примерно так:
    /**
     * Test
     * @ORM\Table(name="test")
     * @ORM\Entity
     */
    class Test {
        /**
         * @var integer
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue
         */
        private $id;
    
        /**
         * @ORM\OneToMany(targetEntity="Acme\AppBundle\Entity\Breakagedemand", mappedBy="test", cascade={"persist"})
         */
        private $collection;
    
        public function __construct()
        {
            $this->collection = new ArrayCollection();
        }
    
        ...
    
        public function addCollection( Breakagedemand $breakagedemand )
        {
            // Устанавливаем  для каждого добавляемого в коллекцию элемента  тест, к которому он относится
            $breakagedemand->setTest($this);
    
            // И только после этого добавляем его в коллекцию
            $this->collection[] = $breakagedemand;
    
            return $this;
        }
    
        ...
    }


    А сущность Breakagedemand так:
    /**
     * Breakagedemand
     * @ORM\Table(name="breakagedemand")
     * @ORM\Entity
     */
    class Breakagedemand {
        /**
         * @var integer
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue
         */
        private $id;
    
    
        // cascade={"persist"} тут не нужен, с этой стороны мы не будем редактировать сущность Breakage
        // Название сущности выбрано неверное, так как тут не будет никакого ID, а будет экземпляр сущности Breakage
        /**
         * @var integer
         * @ORM\ManyToOne(targetEntity="Acme\AppBundle\Entity\Breakage", inversedBy="breakagedemands")
         * @ORM\JoinColumn(name="posbreakage_id", referencedColumnName="id")
         */
        private $posbreakage;
    
    
    
        // cascade={"persist"} тут не нужен, с этой стороны вы тест добавлять никогда не будете
        // referencedColumnName="id" должен быть ID - так как мы связываем после по ИД с таблицей тестов
    
        /**
         * @ORM\ManyToOne(targetEntity="Acme\AppBundle\Entity\Test", inversedBy="collection")
         * @ORM\JoinColumn(name="test_id", referencedColumnName="id")
         */
        private $test;
    
    
        // $this->test не является коллекцией, не надо объявлять new ArrayCollection() в конструкторе
        public function __construct()
        {
        }
    
        // соответственно метод должен быть не addTest а setTest
        public function setTest(Test $test = null)
        {
            $this->test = $test;
    
            return $this;
        }
    
        public function getTest()
        {
            return $this->test;
        }
    
        public function setPosbreakage(Breakage $posbreakage )
        {
            $this->posbreakage = $posbreakage;
            return $this;
        }
    
        /**
         * Get posbreakage
         * @return integer
         */
        public function getPosbreakage()
        {
            return $this->posbreakage;
        }
    
    }


    В комментах я написал где вы накосячили.

    На сколько я понял вашу задачу, у вас есть заранее составленный список возможных поломок. И к тесту надо просто прикрепить некоторые из них. В этом случае вам лучше совсем убрать сущность Breakagedemand и просто сделать связь многие ко многим Test и Breakage(это если в сущности Breakagedemand не хранятся дополнительные данные и если одна поломка не должна добавляться несколько раз):

    /**
     * Test
     * @ORM\Table(name="test")
     * @ORM\Entity
     */
    class Test {
        /**
         * @var integer
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue
         */
        private $id;
    
        /**
         * Список номеров, в котором должно выйти объявление
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="Breakage")
         * @ORM\JoinTable(name="test2breakage",
         *   joinColumns={
         *     @ORM\JoinColumn(name="test_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="breakage_id", referencedColumnName="id")
         *   }
         * )
         */
        private $breakages;
    
        public function __construct()
        {
            $this->breakages = new ArrayCollection();
        }
        public function addBreakage(Breakage $breakage)
        {
    
            $this->breakages[] = $breakage;
    
            return $this;
        }
    
        /**
         * Remove nomer
         *
         * @param Breakage $breakage
         */
        public function removeBreakage(Breakage $breakage)
        {
            $this->breakages->removeElement($breakage);
        }
    
        /**
         * Get nomer
         *
         * @return \Doctrine\Common\Collections\Collection
         */
        public function getBreakages()
        {
            return $this->breakages;
        }
    }
    
    /** 
     * @ORM\Entity
     * 
     **/
    class Breakage
    {
        // ...
    }


    И форма для работы с такой сущностью будет в 100 раз проще:
    public function buildForm(FormBuilderInterface $builder, array $options)
        {
            ...
            $builder->add('breakages', 'entity', array(
                'class' => 'NameSpace\MyBundle\Entity\Breakage',
                'property' => 'name',
                'multiple'  => true
            ));
        }


    Неймспейсы я брал на обум, если что поправите.
    Ответ написан
    Комментировать
  • Как в Twig вывести вывод метода класса?

    @jaxel
    На сколько я знаю в твиге нельзя использовать статичные методы классов.
    Могу предложить 2 варианта:
    1) Создать свой экстеншен для твига, и использовать его на переменной как фильтр
    {{ salonTables.cityId|cityNameFromId }}
    2) Передавать в шаблон экземпляр класса City и использовать метод уже из него.
    {{ city.nameFromId(salonTables.cityId) }}
    Ответ написан
    1 комментарий
  • Какую бесплатную cms/фреймворк использовать для интернет-магазина?

    @jaxel
    Если выбор стоит между CMS и фреймворком, есть довольно простой алгоритм. Если возможности CMS решают 100% задач и быстрого дальнейшего развития не ожидается - надо брать CMS. Если же хотя бы 5% функционала придётся дописывать, лучше взять фреймворк и сделать всё под себя.

    Как показывает практика, эти 5% допилок окажутся такой головной болью в будущем, что сделать 100% функционала на фреймворке будет дешевле и быстрее.
    Ответ написан
    Комментировать