symfony 2 – Блог Stafox'a https://stafox.cc О программировании и веб-разработке Sun, 20 Mar 2016 20:35:20 +0000 en-US hourly 1 https://wordpress.org/?v=5.8.2 Warning: Erroneous data format for unserializing ‘App\UserBundle\Entity\User’ https://stafox.cc/warning-erroneous-data-format-for-unserializing-app-userbundle-entity-user/ https://stafox.cc/warning-erroneous-data-format-for-unserializing-app-userbundle-entity-user/#comments Sun, 20 Mar 2016 20:35:20 +0000 http://stafox.ru/?p=2776 Ошибка Doctrine 2 с FOS\UserBundle. Воспроизводится на PHP 5.6 при использовании FOS/UserBundle для Symfony и старой версии доктрины 2.3.х. Лог такой: Warning: Erroneous data format for unserializing 'App\UserBundle\Entity\User' in project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php Я нашел два способа исправления. Обновить версию Doctrine Обновить Doctrine до версии 2.4.x или выше. Однако не всегда это допустимо, в силу того, что что-нибудь

Сообщение Warning: Erroneous data format for unserializing ‘App\UserBundle\Entity\User’ появились сначала на Блог Stafox'a.

]]>
Ошибка Doctrine 2 с FOS\UserBundle. Воспроизводится на PHP 5.6 при использовании FOS/UserBundle для Symfony и старой версии доктрины 2.3.х.

Лог такой:


Warning: Erroneous data format for unserializing 'App\UserBundle\Entity\User' in project/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php

Я нашел два способа исправления.

Обновить версию Doctrine

Обновить Doctrine до версии 2.4.x или выше. Однако не всегда это допустимо, в силу того, что что-нибудь может отвалиться. А исправить нужно здесь и сейчас 🙂

Изменить способ создания объекта без конструктора

Собственно причина проблемы – это способ, который использует Doctrine для создания объекта без вызова конструктора – десериализация данных.
Можно исправить метод newInstance() и создавать объект через рефлексию.


function newInstance()
{
    if ($this->_prototype === null) {
        if (method_exists($this->reflClass, 'newInstanceWithoutConstructor')) {
            $this->_prototype = $this->reflClass->newInstanceWithoutConstructor();
        } else {
            $this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
        }
    }

    return clone $this->_prototype;
}

Сообщение Warning: Erroneous data format for unserializing ‘App\UserBundle\Entity\User’ появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/warning-erroneous-data-format-for-unserializing-app-userbundle-entity-user/feed/ 1
Symfony 2: парсинг UTF-8 данных с DomCrawler https://stafox.cc/symfony-2-parse-utf-8-data-using-domcrawler/ https://stafox.cc/symfony-2-parse-utf-8-data-using-domcrawler/#respond Sun, 11 Oct 2015 18:27:13 +0000 http://stafox.ru/?p=2678 На днях необходимо было распарсить ресурс в рамках проекта на Symfony 2. Для этого я решил воспользоваться Сrawler’ом – компонентом Symfony, который позволяет работать с DOM элементами, используя при этом XPath и CSS фильтры. Но возникла проблема с кодировкой. Некоторые символы выглядели явно не так, как должны были, несмотря на то, что везде где можно

Сообщение Symfony 2: парсинг UTF-8 данных с DomCrawler появились сначала на Блог Stafox'a.

]]>
На днях необходимо было распарсить ресурс в рамках проекта на Symfony 2. Для этого я решил воспользоваться Сrawler’ом – компонентом Symfony, который позволяет работать с DOM элементами, используя при этом XPath и CSS фильтры. Но возникла проблема с кодировкой.

Некоторые символы выглядели явно не так, как должны были, несмотря на то, что везде где можно использовалась кодировка UTF-8. Дело в том, что Crawler использует кодировку ISO-8859-1 в том случае, если он не смог ее определить по мета-тегу


<meta charset="utf-8">

Исправить проблему можно воспользовавшись методом addHtmlContent(), который вторым параметром принимает кодировку (по умолчанию – UTF-8).

Поэтому вместо


use Symfony\Component\DomCrawler\Crawler;
...
$crawler = new Crawler($html);

нужно использовать


use Symfony\Component\DomCrawler\Crawler;
...
$crawler = new Crawler();
$crawler->addHtmlContent($html);

Сообщение Symfony 2: парсинг UTF-8 данных с DomCrawler появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/symfony-2-parse-utf-8-data-using-domcrawler/feed/ 0
Symfony 2: UniqueEntity и валидация формы https://stafox.cc/symfony-2-uniqueentity-and-form-validation/ https://stafox.cc/symfony-2-uniqueentity-and-form-validation/#respond Sun, 30 Aug 2015 10:53:29 +0000 http://stafox.ru/?p=2642 Есть стандартная задача, с которой наверняка сталкивался каждый веб-разработчик: при добавлении сущности в БД убедиться, что такой еще нет, а если есть, то отобразить соответствующее сообщение. Хочу поделиться реализацией такой задачи в Symfony 2. Конкретный пример: необходимо реализовать функционал подписки на разные почтовые рассылки. Есть несколько вариантов как это можно сделать: можно повесить уникальный индекс

Сообщение Symfony 2: UniqueEntity и валидация формы появились сначала на Блог Stafox'a.

]]>
Есть стандартная задача, с которой наверняка сталкивался каждый веб-разработчик: при добавлении сущности в БД убедиться, что такой еще нет, а если есть, то отобразить соответствующее сообщение. Хочу поделиться реализацией такой задачи в Symfony 2.

Конкретный пример: необходимо реализовать функционал подписки на разные почтовые рассылки.

Есть несколько вариантов как это можно сделать:

  • можно повесить уникальный индекс на поля в таблице и отлавливать определенную ошибку c кодом 23000.
  • можно предварительно делать выборку на наличие такой записи в таблице.

В случае с Doctrine второй вариант предпочтительнее, т.к. в первом случае, при возникновении ошибки Doctrine рвет соединение с БД. Я расскажу о том, как сделать это автоматически при помощи компонентов Symfony.

У нас имеются сущности Newsletter (рассылка) и Subscriber (подписчик).


SubscribeBundle\Entity\Newsletter:
    type: entity
    table: newsletter
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        title:
            type: string
            length: 255
    lifecycleCallbacks: {  }


SubscribeBundle\Entity\Subscriber:
    type: entity
    table: subscriber
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        newsletterId:
            type: integer
            column: newsletter_id
        email:
            type: string
            length: 255
    lifecycleCallbacks: {  }
    manyToOne:
        newsletter:
            targetEntity: Newsletter
            joinColumn:
                name: newsletter_id
                referencedColumnName: id
            cascade: ["persist"]
    uniqueConstraints:
        newsletter_subscriber:
            columns: [ newsletter_id, email ]

Нам понадобится компонент Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity. Для того, чтобы воспользоваться им, необходимо добавить в src/SubscribeBundle/Resources/config/validation.yml следующее:


SubscribeBundle\Entity\Subscriber:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
            fields: [newsletterId, email]
            errorPath: email
            message: 'You already subscribed to this newsletter'

fields – параметр, который указывает на какие поля распространяется условие уникальности.
errorPath – параметр, который указывает на какое поле повесить ошибку (по умолчанию первое поле из параметра fields)
message – сообщение, которое будет показано при нарушении уникальности.

Создадим форму и передадим ей сущность Subscriber.


$subscriber = new \SubscribeBundle\Entity\Subscriber();
$form = $this->createFormBuilder($subscriber , ['attr' => ['id' => 'subscribe_form']])
    ->setAction($this->generateUrl('subscribe'))
    ->add('email', 'email', [
        'constraints' => [new NotBlank(), new Email()],
        'attr' => ['placeholder' => 'Enter your e-mail address...']
    ])
    ->add('newsletter_id', 'hidden', [
        'constraints' => new NotBlank(),
        'data' => 1 // NewsletterId should be here
    ])
    ->add('subscribe', 'submit', [
        'label' => 'Subscribe'
    ])
    ->getForm();

Теперь при валидации формы будет происходить проверка на уникальность почтового адреса для определенной рассылки.


...
$form->handleRequest($request);

if ($form->isValid()) {
    // Save entity to database
} else {
    $errors = $this->getErrorMessages($form);
    // Display somewhere received errors
}

Ну вот в принципе и всё. Для наглядности постараюсь в ближайшее время поделиться бандлом Subscribe.

Сообщение Symfony 2: UniqueEntity и валидация формы появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/symfony-2-uniqueentity-and-form-validation/feed/ 0