RSS Записей | RSS Комментариев
Ядоблог - Stay upwind

Архив ‘PHP’ Категории

Экзамен Zend PHP 5.5 сдан!

января 28, 2014 | 3 комментария

Экзамен Zend PHP 5.5 (код 200-550) сдан. На редкость, сдал с первой попытки.
70 вопросов за 90 минут. От сокетов и потоков до трейтов и генераторов. Половина вопросов с подвохом (передача параметров и значений по ссылке, рекурсивные вызовы, и.т.д.)

Получил профиль на Zend: http://www.zend.com/en/store/education/certification/yellow-pages.php#show-ClientCandidateID=ZEND024577

Кроме статуса ещё плюшки:

  • Уже разместили на жёлтых страничках Zend. Оказывается в России всего ~300 сертифицированных Zend разработчиков за период с 2004 года: жёлтые страницы
  • Кроме статуса, Zend ещё дают ключик на Zend studio и скидку в 25% на любой обучающий курс.
  • Досут к вип группе в линкедине =)

Архитектура приложений. DDD(Domain Driven Design), MongoDB, PHP, скрипты.

марта 10, 2013 | 3 комментария

Размышления о применимости DDD (Domain Driven Design) для веб проектов не дают покоя.
Сразу оговорюсь, что рассуждения касательно применимости не в энтерпрайз, а в своих мелких проектикиках.

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

1. принцип DDD — проектируем модель, а затем думаем как сохранять. Хорошо, если модель легко проектируется на место хранения…
Возможно у меня кривое представление модели, но, под моделью(MVC, DDD) я понимаю большой жирный слой, в котором нужно реализовать следующее:

Интерфейсы, реализация классов объектов(геттеры, сеттеры). Связи между объектами пока опустим.
Обычно не сложно.

Сохранением объектов занимаются мапперы. Проектируем интерфейс маппера и реализуем по 1 мапперу на каждый класс объекта. Что-то простое плоское сохранять и извлекать легко. Идеологически, в коллекциях MongoDB правильно хранить агрегаты. Агрегаты — это сложные объекты, имеющие не плоскую структуру(состоящие из вложенных объектов). Для декомпозиции агрегатов нужен ещё один уровень абстракции. Назовём его Data Abstraction layer(DAL). Но о нём позже.

О реализации маппера, 2 варианта:

  • Dependency Injection, инициатива создания объекта исходит от маппера. При создании объекта передаём ссылку на его маппер.
  • Изначальное наделение объектов информацией о их маппере.

Оба варианта холиварные. Мне нравится второй, т.к. мапперы меняются не так часто(никогда) и получаем автокомплит.

Опять же удобно сделать MappersManager, который будет конструировать мапперов.

IdentityMap для объектов:
Неплохо бы кешировать объекты, чтобы при повторном обращении к мапперу получать данные из кеша, 2 варианта:

  • декоратор к мапперу
  • отдельный компонент, обращение к которому маппер делает самостоятельно

Мне нравится второй, т.к. в маппере могут быть самостоятельные обращения к IdentityMap.

Lazy Load конструирование данных:
При выборке большого количества объектов, маппер возвращает итератор над коллекцией, элементы которой будут созданы только в момент фактического доступа (foreach), 2 варианта:

  • либо отключаем IdentityMap для этой коллекции
  • либо используем инвалидацию хранилища в IdentityMap(сброс кеша).

Инвалидация IdentityMap:
Для этого все создаваемые маппером объекты нужно обернуть в проксирующие дектораторы. Которые декорируют метод объекта getId(), без фактического обращения к объекту. Иногда это выручает, т.к. не всем нужно кроме Id элемента что-то ещё.
Этот проксирующий декоратор позволит создать объект, в случае, если хранилище IdentityMap было инвалидировано.

Зависимые загрузки. Проблема 1+n запросов.
$posts = $user->posts() и затем foreach $posts->comments() фактически вызовет N запросов(для каждого поста по запросу), решается уведомлением зависимого маппера о вероятном использовании некоторых объектов. Например CommentMapper::notifyUsage($comment_id) или MapersManager::getMapper(‘comment’)->notifyUsage($comment_id);
Но для этого нужно отказаться от итератора над коллекцией возвращаемых значений для постов.

Связи. Самое сложное, 2 решения:

  • Анемичная модель: PostService::addComment($post, $comment). В этом случае PostService должен выполнить операцию сам(изменить фактические данные). Для этого он должен знать о реальной структуре хранимых данных. И обращаться ему придётся к Data Abstration Layer, на уровень ниже.
  • Богатая модель: $post->addComment($comment); В этом случае, вероятно, вызов должен быть делегирован обоим мапперам, чтобы каждый выполнил свою часть операции. Хранение связей в MongoDB отличается от реляционной модели. Возможно связь должны хранить оба элемента(тип значения «список» в MongoDB).

Скрипты(отчёты, регламентные процедуры, и.т.д.):

Скрипты в доменной модели, всегда веселуха. Напрямую обращаться к базе нельзя, всё через уровень доменной модели. Медленно.

 

Резюме:

Это только первый слой, без Data Abstration Layer. Выглядит уже сложно. Возникает ощущение программирования ради программирования.

Как возможная альтернатива: Анемичная модель и отказ от объектов пользу массивов. Интеграция приложения на уровне базы данных, когда всё приложение пронизано знанием о способе хранения и структуре возвращаемых данных.

Как показывает опыт анемичная модель доминирует в вебе. Суппорт анемичной модели так же более лёгкое занятие.

IDE для PHP. автокомплит

января 9, 2013 | Комментариев нет

Есть ли IDE, правильно подавтокомплитящие $b->get()-> для следующего кода?:

<?php
  class a {
    public function returnObject() {
      return new object_a();
    }
 
    public function get() {
      return $this->returnObject();
    }
  }
 
  class b extends a {
    public function returnObject() {
      return new object_b();
    }
  }
 
 
  class object_a {
    public $a;
    public $aa;
  }
 
  class object_b {
    public $b;
    public $bb;
  }
 
  $a = new a();
  $a->get()->a;
 
  $b = new b();
  $b->get()->
PHP IAD

Нужны PHP разработчики, Новосибирск, Академгородок

октября 9, 2012 | 1 Комментарий

Нам нужны начинающие и толковые PHP разработчики. Подробнее тут: http://rabota.ngs.ru/vacancy/PHP_programmist?id=3577317

Могу подробнее рассказать что-нить, чего нет в описании вакансии.

sphinx, xmlpipe2, PHP и MongoDB или загибаем трубу из MongoDB в сфинкс, используя PHP

мая 22, 2012 | Комментариев нет

ТЗ: организовать релевантный поиск.

ТУ: данные хранятся в MongoDB, бэкенд на PHP.
Читать полностью »

PHP, добавляем новый метод в уже существующий объект

мая 2, 2012 | Комментариев нет

Допустим у нас есть объект — курсор из субд. Но мы хотим расширить его, для возвращения объектов. Добавить метод next_object(), который будет использовать метод getNext()

Проблема:
Мы не можем заставить модель возвращать объекты другого типа.

Решение 1: сделать итератор на этот курсор(который тоже является итератором). Сделать много магии для методов и свойств и получить новый итератор с нужным нам свойством.

Решение 2: Для PHP 5.4.0, использовать анонимные функции. О нём я и расскажу:
Внутри мапера, в методе findWhere($where) сделаем добавление анонимной функции в курсор, с передачей колбека и самого курсора

	/**
	 * @return MongoCursor
	 */
	public function findWhere($where)
	{
		$collection=$this->collection->find($where);
		$callback=$this;
 
		$collection->next_object=function() use ($collection, $callback)
		{
			$data=$collection->getNext();
			$obj=$callback->create_object($data);
			return ($obj);
		};
		return ($collection);
	}

Теперь, по идее можно обращаться к $collection->next_object() и получать объект, созданный мапером. Но к сожалению это не работает, т.к. PHP попробует выполнить user_func_array и не найдёт метод. Для этого присваиваем свойство переменной, значение которого является анонимной функцией и выполняем, через $func():

	public function findOneWhere($where)
	{
		$collection=$this->findWhere($where);
		$func=$collection->next_object;
		return ($func());
	}

Кривенько, но работает.

Откупонер, агрегатор купонов

марта 26, 2012 | Комментариев нет

Агрегатор купонов http://otkuponer.ru:
Факты:
Агрегируется 22 сайта.
Уже в системе более 64 тысяч купонов.
Из 42 купонных сайтов(кому я написал) дали ответ только 22, остальные или проигнорировали мои письма, или затянули с ответом. Под остальных придётся писать парсеры, если так и не ответят.
Партнёрку предложили 10 сайтов.
Вполне устраивающее меня состояние дел =)

В планах:
1. пинговалка поисковых систем — таки хочу немного поиметь поискового трафика
2. поисковый движок.
3. добавить информационные страницы.

PHP, MongoDB, coursor, count()

марта 20, 2012 | Комментариев нет

Забавная особенность метода count(), применительно к курсору результата запроса.

$items=$collection->find($where)->sort($sort)->limit($limit)->skip($offset*$limit);
var_dump($items->count()); //1
var_dump($items->count(true)); //2

в первом случае получим count всех записей, без учёта limit и skip, но с учётом where
во втором случае получим count записей с учётом limit, skip, where.

MongoDB, PHP IAD

otkuponer.ru / released

февраля 26, 2012 | Комментариев нет

Готова первая версия агрегатора купонов http://otkuponer.ru/ (если не открывается, ждите пока приедут DNS-ы).

Как обычно минимальный дизайн. На текущий момент работает 2 системы купонов(биглион и групон), на подходе купикупон.

Проект выполняется в чистом стиле проектирования по модели предметной области, но без Active Record (ty to CanceRus). Для разработки используется Agile подход.

СУБД юзается MongoDB, программировать мега-приятно (ty to 10gen).

Фреймворк для разработки — старичок CodeIgniter (но по скорости работы он весьма не старичок).

 

В планах сделать парсеры на 100500 сайтов купонов и что-нить улучшить для посетителей.

PHP and MongoDB Web Development Beginner’s Guide (Rubayeet Islam)

февраля 20, 2012 | Комментариев нет

Книга «PHP and MongoDB Web Development Beginner’s Guide (Rubayeet Islam)» достаточна интересна, описывает основные принципы работы с MongoDB из PHP. Читается быстро, за 4-8 часов(если пролистывать примеры =) ). Что особенно порадовало — разбирается map-reduce.

Это единственная книжка, которую нашёл по связке PHP — MongoDB, так что настоятельно рекомендую.

Ещё хотел бы написать о канале #mongodb на IRC freenode. Там более 300 человек, легко идут на контакт, так что велком.

© 2010 Ядоблог. Все права защишены.
Powered by Лаборатория Яда. Написать администратору