PHP – Блог Stafox'a https://stafox.cc О программировании и веб-разработке Wed, 21 Sep 2016 07:13:34 +0000 en-US hourly 1 https://wordpress.org/?v=5.8.2 Как настроить Xdebug в PhpStorm https://stafox.cc/how-to-configure-xdebug-in-phpstorm/ https://stafox.cc/how-to-configure-xdebug-in-phpstorm/#comments Tue, 20 Sep 2016 17:51:19 +0000 http://stafox.ru/?p=2816 Речь пойдет о том, как подружить IDE PhpStorm и Xdebug, чтобы мы могли дебажить не только наши веб-странички и api, а также и консольные скрипты прямо из любимого IDE. Ранее я уже писал о установке и настройке Xdebug и работе с ним через IDE NetBeans. Поэтому если у Вас еще не установлен Xdebug – установите.

Сообщение Как настроить Xdebug в PhpStorm появились сначала на Блог Stafox'a.

]]>
Речь пойдет о том, как подружить IDE PhpStorm и Xdebug, чтобы мы могли дебажить не только наши веб-странички и api, а также и консольные скрипты прямо из любимого IDE.

Ранее я уже писал о установке и настройке Xdebug и работе с ним через IDE NetBeans. Поэтому если у Вас еще не установлен Xdebug – установите.

Большинство статей и заметок я пишу на примере Ubuntu. Поэтому если Вы еще не используете данный дистрибутив, советую ознакомиться с руководством по установке Ubuntu.

Заходим в настройки проекта File → Settings или Ctrl+Alt+S
ps-xdebug-1

Переходим в раздел Languages & FrameworksPHPDebug
И указываем Debug port:
ps-xdebug-2

Обратите внимание на порт, я использую 9009 (если он у Вас занят, укажите любой свободный)

Не стоит использовать для Xdebug порт 9000 (по умолчанию), если Вы используете php-fpm. В таком случае порт будет занят процессом php-fpm и Xdebug работать не будет.

Не закрывая настроек переходим в раздел Languages & FrameworksPHPDebugDBGp Proxy.

В php.ini параметр xdebug.remote_handler должен иметь значение dbgp.

И указываем следующие параметры:

IDE key: phpstorm

В php.ini параметр xdebug.idekey должен быть равен phpstorm.

Host: 127.0.0.1

В php.ini параметр xdebug.remote_host также должен быть 127.0.0.1.

Port: 9009

В php.ini параметр xdebug.remote_port должен быть 9009.

Все. На этом настройка завершена. Теперь для того, чтобы дебажить Вам достаточно поставить break-point и включить слушателя debug-соединений.
ps-xdebug-4

Сообщение Как настроить Xdebug в PhpStorm появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/how-to-configure-xdebug-in-phpstorm/feed/ 11
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
Столбец в качестве ключа для результирующей выборки в Doctrine 2 https://stafox.cc/define-column-as-key-for-result-array-in-doctrine-2/ https://stafox.cc/define-column-as-key-for-result-array-in-doctrine-2/#respond Thu, 08 Oct 2015 06:02:23 +0000 http://stafox.ru/?p=2664 Вернуть в качестве ключа выборки значение одного из столбцов – довольно частая задача. Достичь результата можно несколькими способами. INDEX BY createQuery() Если Вы создаете запрос используя createQuery, то достаточно добавить к конструкции FROM конструкцию INDEX BY column_name. namespace DemoBundle\Repository; use Doctrine\ORM\EntityRepository; class SettingsRepository extends EntityRepository { public function getSettingsIndexedByName() { $query = $this->createQuery('SELECT s FROM

Сообщение Столбец в качестве ключа для результирующей выборки в Doctrine 2 появились сначала на Блог Stafox'a.

]]>
Вернуть в качестве ключа выборки значение одного из столбцов – довольно частая задача. Достичь результата можно несколькими способами.

INDEX BY

createQuery()
Если Вы создаете запрос используя createQuery, то достаточно добавить к конструкции FROM конструкцию INDEX BY column_name.


namespace DemoBundle\Repository;

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository
{
    public function getSettingsIndexedByName()
    {
        $query = $this->createQuery('SELECT s FROM DemoBundle:Settings s INDEX BY s.name');
        return $query->getResult();
    }
}

createQueryBuilder()
Но Вы наверняка используете QueryBuilder для создания запросов, он также позволяет использовать indexBy. Метод createQueryBuilder принимает два параметра: alias и indexBy.


namespace DemoBundle\Repository;

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository
{
    public function getSettingsIndexedByName()
    {
        $qb = $this->createQueryBuilder('s', 's.name')
            ->select('s');
        $query = $qb->getQuery();
        return $query->getResult();
    }
}

Однако в предыдущих версиях Doctrine (например 2.4.7) метод createQueryBuilder выглядит следующим образом.


public function createQueryBuilder($alias)
{
    return $this->_em->createQueryBuilder()
        ->select($alias)
        ->from($this->_entityName, $alias);
}

Как видите, нет параметра indexBy. Решить эту проблему можно расширив класс Doctrine\ORM\EntityRepository.


namespace DemoBundle\Repository;

use Doctrine\ORM\EntityRepository as DoctrineEntityRepository;

class EntityRepository extends DoctrineEntityRepository
{
    public function createQueryBuilder($alias, $indexBy = null)
    {
        return $this->_em->createQueryBuilder()
            ->select($alias)
            ->from($this->_entityName, $alias, $indexBy);
    }
}

Теперь Вам нужно только унаследовать от него свои классы-репозитории и воспользоваться переопределенным методом createQueryBuilder()

Hydrators

Также изменить вид результирующей выборки можно при помощи гидраторов. Но это уже тема для отдельной статьи.

Сообщение Столбец в качестве ключа для результирующей выборки в Doctrine 2 появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/define-column-as-key-for-result-array-in-doctrine-2/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
Как получить количество лайков c Facebook Graph API v2 https://stafox.cc/how-to-get-page-likes-using-facebook-graph-api-v2/ https://stafox.cc/how-to-get-page-likes-using-facebook-graph-api-v2/#respond Fri, 07 Aug 2015 20:48:18 +0000 http://stafox.ru/?p=2603 Facebook запустил Graph API v2.0, а 30 апреля 2015 года прекратил поддержку версии v1.0. Мне понадобилось вытянуть количество лайков для страницы. Делюсь способом как это можно сделать. Вам понадобится OAuth2 access token для получения данной информации. Как его получить читайте документацию. $facebookPageId = 'pageNameOrId'; $accessToken = 'OAuthAccessToken'; /** * You may also add another fields

Сообщение Как получить количество лайков c Facebook Graph API v2 появились сначала на Блог Stafox'a.

]]>
Facebook запустил Graph API v2.0, а 30 апреля 2015 года прекратил поддержку версии v1.0. Мне понадобилось вытянуть количество лайков для страницы. Делюсь способом как это можно сделать.

Вам понадобится OAuth2 access token для получения данной информации. Как его получить читайте документацию.


$facebookPageId = 'pageNameOrId';
$accessToken = 'OAuthAccessToken';
/**
 * You may also add another fields to get (link, name, website and other)
 * @see https://developers.facebook.com/docs/graph-api/reference/page
 */
$fields = implode(',', array('likes'));
$url = "https://graph.facebook.com/v2.4/{$facebookPageId}?fields={$fields}&access_token={$accessToken}";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($curl);
curl_close($curl);
$details = json_decode($result);
echo $details->likes;

Application Access Token

Если Вы будете делать запрос от имени приложения, то можно получить данные, сделав всего один запрос к Graph API.
Дело в том, что Facebook Graph API v2 позволяет в качестве access token использовать пару appId и appSecret, разделив их |.
В таком случае url будет выглядеть следующим образом:


/**
 * @see https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
 */
$url = "https://graph.facebook.com/v2.4/{$facebookPageId}?fields={$fields}&access_token={$appId}|{$appSecret}";

Сообщение Как получить количество лайков c Facebook Graph API v2 появились сначала на Блог Stafox'a.

]]>
https://stafox.cc/how-to-get-page-likes-using-facebook-graph-api-v2/feed/ 0