Показаны сообщения с ярлыком php. Показать все сообщения
Показаны сообщения с ярлыком php. Показать все сообщения

вторник, 13 января 2015 г.

Установка Gearman на Ubuntu

Проблема:

Старые версии Ubuntu не содеждат последние Gearman библиотеки. Если вы попробуете установить PHP расширение для Gearman на Ubuntu, то получите ошибку. Далее приведены шаги по установке Gearman библиотех и PHP расширения на Ubuntu 10.04 LTS и следующие версии.

Добавляем PPA репозиторий для получения последней версии libgearman:

$ sudo apt-add-repository ppa:gearman-developers
$ sudo apt-get update
$ sudo apt-get install libgearman7 libgearman-dev

Устанавливаем Job Server:

$ sudo apt-get install gearman-job-server

Устанавливаем PHP расширение с помощью PECL:

$ sudo pecl install gearman

Активируем PHP расширение:

$ echo "extension=gearman.so" | sudo tee /etc/php5/conf.d/gearman.ini

Тестируем:

Все готово для тестирования. Для этих целей можно использовать пример с официального сайта Gearman:
http://gearman.org/examples/reverse/
Читать далее

понедельник, 15 декабря 2014 г.

Magento: Как очистить DB Connections при форке процесса

На данный момент работаю над интеграцией Gearman в Magento. Для создания child-процессов использую PCNTL PHP extension. Все шло гладко, но при тестировании я столкнулся с ошибкой "SQLSTATE[HY000]: General error: 2006 MySQL server has gone away". Проблема в том что при инициализации Magento приложения DB connections кешируются в Mage_Core_Model_Resource::$_connections и будут использоваться для всех форков родительского скрипта. Решение проблемы очень простое –– в дочернем скрипте необходимо удалить 'core/resource' из реестра:

/**
 * Reset DB connections for preventing "SQLSTATE[HY000]: General error: 2006 MySQL server has gone away"
 *
 * @return $this
 */
protected function _resetDbConnections()
{
    Mage::unregister('_singleton/core/resource');
    return $this;
}

Читать далее

воскресенье, 15 июня 2014 г.

Magento: Как добавить во flat таблицу аттрибут с собственной source моделью

Для добавления атрибута продукта во flat таблицу достаточно выполнить следующие действия:
1. Включить для атрибута настройку "Used in Product Listing"
2. Выполнить полный реиндекс catalog_product_flat

Но это не работает если вы создаете атрибут с собственной source моделью. Чтобы сделать это нужно выполнить несколько дополнительных действий:
1. Добавить в source модель функцию getFlatColums() с описанием вашего атрибута. Да да, именно getFlatColums, а не getFlatColumns (привет core разработчикам Magento).
/**
 * {@inheritdoc}
 */
public function getFlatColums()
{
    return array($this->getAttribute()->getAttributeCode() => array(
        'type'      => 'tinyint',
        'unsigned'  => true,
        'is_null'   => true,
        'default'   => null,
        'extra'     => null
    ));
}

2. Добавить функцию getFlatUpdateSelect()
/**
 * {@inheritdoc}
 */
public function getFlatUpdateSelect($store)
{
    /** @var $attr Mage_Eav_Model_Resource_Entity_Attribute */
    $attr = Mage::getResourceSingleton('eav/entity_attribute');
    return $attr->getFlatUpdateSelect($this->getAttribute(), $store);
}

После этих действий не забываем выполнить полный реиндекс catalog_product_flat.
Читать далее

суббота, 7 сентября 2013 г.

Установка расширения SHH2 для PHP на CentOS

Установить расширение SHH2 для PHP на CentOS очень просто. Его нельзя поставить через yum install, но все-равно установка сводится к выполнению нескольких простых шагов.

Перед установкой необходимо проверить, что у вас установлен репозиторий EPEL. Если у вас отсутствует данный репозиторий, то перейдите на http://fedoraproject.org/wiki/About_EPEL и следуйте инструкциям.

После того как репозиторий EPEL установлен, можно приступать к установке завимостей.
yum install gcc php-devel php-pear libssh2 libssh2-devel

Это позволит нам установить расширение SSH2 для PHP с помощью pecl.
pecl install -f ssh2

Экстеншен установлен. Дайте опишем конфиг чтобы PHP мог использовать данное расширение.
touch /etc/php.d/ssh2.ini
echo extension=ssh2.so > /etc/php.d/ssh2.ini

Если вы всё сделали правильно, то при выполнении следующей команды вы получите строку с "ssh2".
php -m | grep ssh2

Расширение SSH2 готово к использованию. Не забудьте перезагрузить веб-сервер ;)
Читать далее

вторник, 5 февраля 2013 г.

PHP: особенности функции ip2long

Думаю, большинство программистов встречались с задачей хранения ip в БД. Хранить их как plain text (например, 127.0.0.1) неудобно и непрактично. Потому принято использовать функцию ip2long, которая преобразовывает ip адрес в целове число.

Но есть некоторые особенности ее использования в x32/x64. Допустим, для его хранения мы выделяем INT ячейку в БД.

Результат функции на x32:
ip2long(127.127.127.127) = 2147483648
ip2long(255.255.255.255) = -2147483648

Результат функции на x64:
ip2long(127.127.127.127) = 2147483648
ip2long(255.255.255.255) = 4294967296

Получается что 4294967296 не запишется в БД, так как ячейка в нашей БД типа INT и максимальное число, которое можно в нее записать: 2147483648.

Потому добавляем для атрибут UNSIGNED, который позволяет записывать в БД диапазон чисел от 0 до 4294967296.

Но как же быть с x32? Ведь в ней функция ip2long может вернуть отрицательное значение. Для решения этой проблемы нужно обрабатывать результат перед записью БД:
$ip = sprintf('%u', ip2long($ip)); // возвращает строку с положительным значением

Читать далее

воскресенье, 20 января 2013 г.

PHP: кавычки в str_replace()

Недавно передо мной стала задача удаления некоторых ASCII Device Control Characters из текста. Поскольку удалять нужно было определенные символы, я решил использовать str_replace(). В процессе имплементации было обнаружено разное поведение функции, в зависимости от типа кавычек, в которых мы передаем первый параметр.

Одинарные кавычки
str_replace('\x07', '', $text);
В этом случае функция ищет вхождения плейнтекста '\x07'.

Двойные кавычки
str_replace("\x07", '', $text);
В этом случае функция ищет вхождения ASCII символа '\x07'.
Читать далее

пятница, 18 мая 2012 г.

Magento: Не работает addAttributeToFilter()?

Если вы удивляетесь почему код
$collection->addAttributeToFilter('color', '24');
не фильтрует коллекцию, это означает что в бекенде у данного атрибута не включен параметр "Used in product listing?". Как это ни странно, Magento добавляет атрибут в таблицу catalog_product_flat только если этот параметр включен. Если же он выключен, ни о какой фильтрации не может быть и речи. После включения "Used in product listing?" не забудьте сделать реиндекс.
Читать далее

вторник, 3 апреля 2012 г.

Magento: Добавление нового атрибута для кастомера

В Magento Community Edition присутствует возможность управления атрибутами продуктов. Но что если нам нужно создать атрибут для кастомера? В таком случае нам на помощь приходит mysql upgrade.

Допустим, я хочу создать атрибут "navoq_textmagic_phone", в котором будет храниться телефон кастомера для моего модуля. Пример кода:
/* @var $installer Navoq_TextMagic_Model_Resource_Setup */
$installer = $this;

$installer->startSetup();

$installer->addAttribute('customer', 'navoq_textmagic_phone', array(
    'label'    => 'Phone',
    'visible'  => true,
    'required' => false,
    'type'     => 'text',
    'input'    => 'text'
));

/** @var $eavConfig Mage_Eav_Model_Config */
$eavConfig = Mage::getSingleton('eav/config');

/** @var $attribute Mage_Customer_Model_Attribute */
$attribute = $eavConfig->getAttribute('customer', 'navoq_textmagic_phone');
$attribute->addData(array(
    'is_used_for_customer_segment' => true,
    'used_in_forms'   => array('customer_account_edit', 'adminhtml_customer'),
    'is_user_defined' => true,
    'backend_type'    => 'varchar',
    'is_system'       => false,
    'is_visible'      => true,
    'is_unique'       => false,
    'sort_order'      => 250
))->save();

$installer->endSetup();

Результатом выполнения апгрейда будет новый атрибут кастомера. Таким способом можно создавать атрибуты для разных сущностей: customer, customer_address, etc. Их полный список можно посмотреть в таблице "eav_entity_type".
Читать далее

пятница, 24 февраля 2012 г.

О сравнениях в PHP

Поговорим немного о code style. В частности, о сравнениях. Я рекомендую всегда первым ставить то значение, с которым вы сравниваете. Например:
define('MY_AUTO', 'KIA');

if (MY_AUTO == $_GET['auto']) {
    echo "it's my auto!";
}

О красоте говорить не будем, так как это очень растяжимое понятие. Преимущество данной записи состоит в том, что вы не сможете случайно забыть одно равно и обезопасите себя от такой маленькой и досадной ошибки:
define('MY_AUTO', 'KIA');

if ($_GET['auto'] = MY_AUTO) {
    echo "it's my auto!";
}

Данная проверка всегда будет проходить. С первого раза и не поймешь в чем дело. При первом варианте такое не прокатит. Программируйте внимательно ;)
Читать далее

четверг, 23 февраля 2012 г.

Изолируем тесты в PHPUnit

Вчера столкнулся с ситуацией, когда из-за неправильного кода (в темплейте инициализировалась функция) падали тесты. Например, есть файл index.phtml с таким содержанием:
...
function showMenu()
{
    echo '
  • item1
  • item2
  • item3
'; } ...

Функция showMenu() выводит меню на странице. Программист по каким-то своим соображениям не захотел ее выносить в php-файл. Если мы заходим покрыть данный файл тестами, то уже на втором тесте получим фатал:
PHP Fatal Error: Cannot redeclare showMenu() (previously declared in /home/test/index.phtml) 

Самым лучшим выходом из данной ситуации будет рефакторинг кода: вынести функцию в php-файл или обернуть ее проверкой function_exist():
...
if (!function_exist('showMenu')) {
    function showMenu()
    {
        echo '
  • item1
  • item2
  • item3
'; } } ...

Но что делать когда мы не имеем права редактировать существующий код (в моей практике такое бывает очень часто)? Тогда нам на помощь приходят аннотации PHPUnit @runInSeparateProcess и @runTestsInSeparateProcesses. Они помогают изолировать тест-кейсы, запуская их в отдельных процессах.

@runTestsInSeparateProcesses позволяет изолировать все тест-кейсы:
/**
 * @runTestsInSeparateProcesses
 **/
class MyTest extends PHPUnit_Framework_TestCase
{
    public function testTest1()
    {
        // ...
    }

    public function testTest2()
    {
        // ...
    }
}

@runTestsInSeparateProcesses позволяет изолировать определенные тест-кейсы:
class MyTest extends PHPUnit_Framework_TestCase
{
    public function testTest1()
    {
        // ...
    }

    /**
     * @runInSeparateProcess
     **/
    public function testTest2()
    {
        // ...
    }
}

Надеюсь, эти аннотации помогут вам так же сильно, как помогли сегодня мне. Программируйте правильно о_О
Читать далее

пятница, 27 января 2012 г.

PhpStorm: включаем обрамление выделенного текста в кавычки или скобки

Моя основная IDE на работе и дома это PhpStorm. Причем, в обоих местах она лицензионная ;)

Эта система очень большая, почти каждый день я узнаю что-то новое о ней. Потому решил писать об этом в блоге.

Начнем с обрамления выделенного текста в кавычки или скобки. Сначала это нужно включить.

1. Открываем настройки:

2. Заходим в IDE Settings -> Editor -> Smart Keys и ставим галочку напротив Surround selection on typing quote or brace:

3. Сохраняем настройки и радуемся жизни. Теперь вы можете выделить текст и нажать символ кавычки/скобки, после чего текст будет обрамлен введенным символом.
Читать далее

четверг, 26 января 2012 г.

Как установить PHPUnit для MAMP

На работе я привык работать в CentOS/FreeBSD VM, на которой установлен Apache, nginx, PHP, MySQL и прочие необходимые инструменты для веб-разработки. Это удобно тем, что эта система максимально приближена к реальной обстановке проекта,чем минимизируются основные проблемы, связанные с настройкой различных сервисов.
Ну и VM всегда можно забекапить ;) По-этому, всегда можно безопасно экспериментировать.

Дома у меня MacBook с 2.5 Гб ОЗУ. С виртуалкой все очень тормозит. По-этому до того момента, пока я не разживусь еще одной планкой ОЗУ, приходится юзать MAMP. Вчера появилась задача настройки и запуска PHPUnit для MAMP. Приступим.

Для установки PHPUnit с помощью MAMP PEAR нам потребуется терминал с правами root-пользователя.

Сначала обноляем PEAR с помощью двух команд:
/Applications/MAMP/bin/php5/bin/pear channel-update pear.php.net
/Applications/MAMP/bin/php5/bin/pear upgrade pear

Теперь пришло время зарегистрировать соответствующий канал и установить PHPUnit:
/Applications/MAMP/bin/php5/bin/pear channel-discover pear.phpunit.de
/Applications/MAMP/bin/php5/bin/pear install phpunit/PHPUnit

PHPUnit теперь установлен, но чтобы запускаеть его с помощью терминала, нам нужно перенести его в $PATH:
mv /Applications/MAMP/bin/php5/bin/phpunit /usr/local/bin/phpunit

Для теста наберите:
phpunit --version

Вы увидите что-то вроде:
PHPUnit 3.6.9 by Sebastian Bergmann

Это все. Если есть вопросы, задавайте их в комментариях.
Читать далее

четверг, 19 января 2012 г.

Проверка наличия класса

Если вам нужно проверить наличие определенного класса, вы можете использовать функцию class_exists(). Ее важная особенность состоит в том, что class_exists() даже при отсутствии проверяемого класса автоматически вызывает автолоадер. Чтобы запретить такое поведение, необходимо передавать false в качестве второго параметра фунции class_exists().

Следующий код демонстрирует такое поведение:
    require_once('Zend/Loader.php');
 
    Zend_Loader::registerAutoload();
 
    if (!class_exists('MyTestClass')) {
       // class doesn't exist, but now the auto-loader will try and load it
    }
 
    if (!class_exists('MyOtherTestClass', false)) {
        // class doesn't exist, and the auto-loader will not be used
    }

Читать далее

четверг, 29 декабря 2011 г.

Новогоднее поздравление из Индии

$productIds = array();
foreach ($ids as $categoryId) {
    $category = Mage::getModel('catalog/category')->load($id);
    if ($category->getId()) {
        foreach ($category->getProductCollection() as $product) {
            $productIds[] = $product->getId();
        }
    }
}

Читать далее

вторник, 13 декабря 2011 г.

Интересное поведение PHPUnit_Framework_Assert::assertEquals()

Сегодня узнал интересное поведение PHPUnit_Framework_Assert::assertEquals().

Данная проверка проходит так:
$result = true;
$this->assertEquals('You have not enough rights', $result, "bla bla bla");

и так:
$result = 'You have not enough rights';
$this->assertEquals('You have not enough rights', $result, "bla bla bla");

Интересно, правда? Чтобы тесты вернули свою актуальность, необходимо добавить еще один асерт - PHPUnit_Framework_Assert::assertInternalType():
$result = true;
$this->assertInternalType('string', $result);
$this->assertEquals('You have not enough rights', $result, "bla bla bla");

Читать далее

пятница, 14 октября 2011 г.

Реиндекс в Magento с помощью модели

Иногда необходимо сделать реиндекс в Magento прямо в PHP коде. Сделать это можно так:
$processCollection = Mage::getResourceModel('index/process_collection');
/** @var $process Mage_Index_Model_Process */
foreach ($processCollection as $process) {
    $process->reindexAll();
}

Читать далее

воскресенье, 28 августа 2011 г.

Получение статуса авторизации кастомера в Magento

Всем привет!

Хочу вам показать простой, но очень важный скрипт проверки статуса авторизации кастомера в Magento:
/** @var $session Mage_Customer_Model_Session  */
$session = Mage::getSingleton('customer/session');
if ($session->isLoggedIn()) {
    // logged in
} else {
    // not logged in
}

Читать далее

Отключение "Billing Agreements" и "Recurring Profiles" в Magento

Всем привет!

Среди новых функциональностей, введенных в Magento 1.4.1.0, появились "Billing Agreements" и "Recurring Profiles".

Но они не всегда нужна, а отключить их из админки не является возможным.

Для скрытия ссылок с блока навигации кастомера в "My Account", вы можете скопировать billing_agreement.xml и recurring_profile.xml с /app/design/frontend/base/default/layout/sales/ в /app/design/frontend/default/yourtheme/layout/sales/.

После копирования файлов в их новое месторасположение вы должны отредактировать их. Найдите следующий код в billing_agreement.xml:

    
        billing_agreementssales/billing_agreement/
    


Замените его на:

    
        
    


Найдите следующий код в recurring_profile.xml:

    
        recurring_profilessales/recurring_profile/
    


Замените его на:

    
        
    


Внимание! С помощью этих действий вы только удалите ссылки с блока навигации, но не отключите функциональность.
Читать далее

суббота, 1 января 2011 г.

Обнаружение iPad с помощью PHP



Месяц назад я стал обладателем iPad. Я не буду рассказывать о всех прелестях и перспективах данного продукта, т.к. для этого есть специализированные обзоры.

Наверняка, каждый веб-разработчик захочет кастомизировать свой дизайн под посетителей с "таблетками". Поскольку user agent сего девайса имеет вид:
Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10
делается это очень просто:
$isiPad = (bool) strpos($_SERVER['HTTP_USER_AGENT'],'iPad');

Если вы хотите создать отдельную мобильную версию сайта, то достаточно отредактировать .htaccess:
RewriteCond %{HTTP_USER_AGENT} ^.*iPad.*$
RewriteRule ^(.*)$ http://ipad.yourdomain.com [R=301]

Читать далее

среда, 18 ноября 2009 г.

Определение скорости работы php-скрипта

$start1=gettimeofday();

for($i = 0; $i < 10000; $i++)
{
// do nothing
}

$end1 = gettimeofday();
$totaltime1 = (float)($end1['sec'] - $start1['sec']) + ((float)($end1['usec'] - $start1['usec'])/1000000);

echo "$totaltime1\n";

Читать далее