RSS Feed
Окт 6

Memcached + Doctrine + Zend Framework

Posted on Вторник, октября 6, 2009 in Doctrine, php, ZendFramework, Новости

Совмещаем все это вместе, получаем неплохое ускорение работы доктрины.

Ставим memcached

Как Установить Memcached на windows?

  1. качаем отсюда бинарник http://code.jellycan.com/memcached/
  2. ложим в c:\memcached (или другой путь)
  3. из консоли инсталим как сервис c:\memcached\memcached.exe -d install

Установка под *nix ищется на ура в гугли.

bootstrap

(привожу весь код инитера доктрины)

    /*
     * Init Doctrine
     */
 
    protected function _initDoctrine()
    {
    	$config=$this->getOption('database');
 
    	require_once 'Doctrine.php';
        $autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->registerNamespace('Doctrine');
 
        try {
		Doctrine_Manager::connection("mysql://".$config['params']['username'].":".$config['params']['password']."@".$config['params']['host']."/".$config['params']['dbname'])->setCharset($config['charset']);
        } catch (Exception $e) {
    		echo 'FATAL ERROR: MySql is down'; exit;
	}
 
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_AGGRESSIVE);
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);
	Doctrine::loadModels(APPLICATION_ROOT . "/models");
 
	// Install Tables
        Doctrine::createTablesFromModels(APPLICATION_ROOT . "/models");
 
	// Cache
	$configCache=$this->getOption('cache');
 
	    // Clearer --------------------------------------------------------
	    $memcache_obj = new Memcache;
		$con=$memcache_obj->connect($configCache['host'], $configCache['port']);
		if ($con==FALSE) { echo 'FATAL ERROR: MemCache is down'; exit; }
 
		//$memcache_obj->flush(); // отчистка кеша
 // ---------------------------------------------------------------
 
	    $servers = array(
		    'host' => $configCache['host'],
		    'port' => $configCache['port'],
    		'persistent' => true
             );
 
	$cacheDriver = new Doctrine_Cache_Memcache(array(
	        'servers' => $servers,
	       	'compression' => false
	    )
	);
 
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_QUERY_CACHE, $cacheDriver);
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_QUERY_CACHE_LIFESPAN, 3600);
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_RESULT_CACHE, $cacheDriver);
	Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_RESULT_CACHE_LIFESPAN, 3600);
    }

Все проинииализили и сказали Doctrine что нужно использовать memcache при запросах и выдачи результата

Если у вас в проекте есть Zend_Translate то подцепляем и его:

$configCache=$this->getOption('cache');
 
$backendOptions=array(
		'host' => $configCache['host'],
		'port' => $configCache['port'],
		'persistent' => true
);
$cache = Zend_Cache::factory('Core',
		'Memcached',
		$frontendOptions,
		$backendOptions);
 
Zend_Translate::setCache($cache);

везде используются данные из конфига (ini) вот кусок:

; cache memcached
cache.host	=	localhost
cache.port	=	11211

Запросы

1. После тестов, прямые запросы (DQL) выполняются намного шустрей, т.е.:

$q = Doctrine_Query::create()
->select('id, url')
->from('NewsCategories');
 
$newsCategories= $q->execute()->toKeyValueArray("id","url");

Намного шустрей чем удобное

$newsCategories=Doctrine::getTable("NewsCategories")->findAll()->toKeyValueArray("id","url");

и плюс, в последнем запросе нельзя указывать что нужно использовать кеш (!!!)

теперь все свои запросы приводим в вид «юзай кеш»

$q = Doctrine_Query::create()
->select('id, url')
->from('NewsCategories')
->useCache();
 
$newsCategories= $q->execute()->toKeyValueArray("id","url");

все =)

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 189

Июл 19

Doctrine Accessors и Mutators

Posted on Воскресенье, июля 19, 2009 in Doctrine, php

Очень часто пароль мы хешируем, для этого есть замечательный метод hasMutator.

Пример модели:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class User extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('username', 'string' 255);
        $this->hasColumn('password', 'string', 255);
    }
 
    public function setUp()
    {
       $this->hasMutator('password', 'md5Password');
    }
 
    public function md5Password($value)
    {
        $this->_set('password', md5($value));
    }
}

и теперь когда мы работаем с созданием модели, апдейтом и т.д. можно просто писать так

1
2
3
4
        $user=new Users();
        $user->username="aa";
        $user->password="haha";
        $user->save();

в базе будет положена колонка с паролем в md5

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 46

Июл 19

Doctrine & Zend Framework 1.8 (zf1.8)

Posted on Воскресенье, июля 19, 2009 in Doctrine, php, ZendFramework, Новости

В ветке 1.8 были изменены методы инициалиции, в частности все вынесенно в Bootstrap.php. Теперь о том как подключить Doctrine к ZF 1.8.4.

В конфиге (application/configs/application.ini) :

1
2
3
4
5
6
database.adapter			=	PDO_MYSQL
database.params.host			=	localhost
database.params.username		=	dbloging
database.params.password		=	dbpass
database.params.dbname			=	dbname
database.charset			=	utf8

В application/Bootstrap.php добавляем :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    protected function _initDoctrine()
    {
    	$config=$this->getOption('database');
 
    	require_once 'Doctrine.php';
        $autoloader = Zend_Loader_Autoloader::getInstance();
        $autoloader->registerNamespace('Doctrine');
 
		Doctrine_Manager::connection("mysql://".$config['params']['username'].":".$config['params']['password']."@".$config['params']['host']."/".$config['params']['dbname'])->setCharset($config['charset']);
		Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_AGGRESSIVE);
		Doctrine_Manager::getInstance()->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);
 
		Doctrine::loadModels(APPLICATION_PATH . "/models");        
    }

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 51

мая 13

Обновления Zend Framework 1.8.1 и Doctrine 1.1.1

Posted on Среда, мая 13, 2009 in Doctrine, ZendFramework, Новости

Обновляемся  на новые версии фреймворка и doctrine.

Zend Framework качаем тут:
http://framework.zend.com/download/latest

обзор прошлой версии смотрим тут
http://devzone.zend.com/article/4524-Zend-Framework-1.8.0-Released

В данной версии исправленно более 68 ошибок в коде,  ошибки в документации и «Быстром старте». Так же сделанны изменения (без перевода)

  • Zend_Loader::registerAutoload() now proxies to Zend_Loader_Autoloader, and marks the instance as a fallback autoloader. This will ensure equivalent functionality, and reduces the number of deprecation notices emitted to one.
  • Many bugfixes and improvements to Zend_Application.
  • Addition of module generation capabilities to Zend_Tool
  • Addition of strong object typing capabilities to Zend_Amf
  • Many more manual translations!

Полный список тут: http://short.ie/zf1-8-1-issues

Doctrine

Качаем как обычно с http://www.doctrine-project.org/download

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 21

Мар 19

Doctrine 1.1 Released !

Posted on Четверг, марта 19, 2009 in Doctrine, php, Новости

Сегодня была зарелизина Doctrine 1.1 !

Новшества:
* Новый hydration метод
* Новый иструмент для «объединений» миграций
* Улучшена поддержка и интеграция для accessor и mutator в fromArray() и toArray()
* Усовершенствования в getModified(), toArray(), fromArray(), synchronizeWithArray()
* Усовершенствования ядро для поиска, SoftDelete, Versionable
* и т.д.

Более подробную информацию о новшествах можно прочитать тут http://www.doctrine-project.org/upgrade/1_1

Скачать Doctrine 1.1

или обновляем по svn:

$ svn co http://svn.doctrine-project.org/tags/1.1.0/lib doctrine

upd: Нашел удобную для себя функцию:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$q = Doctrine_Query::create()
    ->from('User u');
$users = $q->execute();
 
$array = $users->toKeyValueArray('id', 'name');
print_r($array);
 
/*
array(
  4 => 'zYne',
  5 => 'Arnold Schwarzenegger',
  6 => 'Michael Caine',
  7 => 'Takeshi Kitano',
  8 => 'Sylvester Stallone',
  9 => 'Kurt Russell',
  10 => 'Jean Reno',
  11 => 'Edward Furlong',
)
*/

Что есть очень удобно для передачи потом виеву для формирование полей значений для select!

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 15

Мар 8

Doctrine Profiler

Posted on Воскресенье, марта 8, 2009 in Doctrine, ZendFramework, Новости

Иногда полезно видеть какие запросы строит Doctrine и сколько времени они выполняются. Описание профайлера в оригинале тут: http://www.doctrine-project.org/documentation/manual/1_1/en/component-overview#profiler

Ниже мой пример.

1. В Initializer.php

public function initDb()
   {
...
        $profiler = new Doctrine_Connection_Profiler ();
        Doctrine_Manager::getInstance()->setListener($profiler);
        Zend_Registry::set('dbProfiler', $profiler);
...

2. В bootstrap.php

...
//В конце файла
$profiler=Zend_Registry::get('dbProfiler');
echo "<div class=box style=\"font-family: Courier New; font-size: 11px\">";
$time = 0;
foreach ( $profiler as $event ) {
$time += $event -> getElapsedSecs ();
echo "<b><font color=red>".$event ->getName () . "</font></b> [" . sprintf ("%f", $event -> getElapsedSecs ()) . "]<br>\n";
echo $event ->getQuery () . "<br>\n";
$params = $event ->getParams ();
if( ! empty ( $params )) {
    var_dump ( $params );
    echo "<br>";
    }
}
echo "<br><b>Total time : " . $time . "</b><br>\n";
echo "</div>";
...

В итоге при каждом генерировании страницы, внизу, мы увидем профайл doctrine, к примеру вот так:

query [0.001810]
SELECT l.id AS l__id, l.date AS l__date, l.username AS l__username, l.ip AS l__ip, l.text AS l__text, l.created_at AS l__created_at, l.updated_at AS l__updated_at FROM logs l ORDER BY l.date DESC LIMIT 20
prepare [0.000102]
SELECT u.id AS u__id, u.status AS u__status, u.role AS u__role, u.username AS u__username, u.password AS u__password, u.email AS u__email, u.im AS u__im, u.lastlogin AS u__lastlogin, u.ballance AS u__ballance, u.created_at AS u__created_at, u.updated_at AS u__updated_at FROM users u WHERE u.id = ? LIMIT 1
execute [0.002061]
SELECT u.id AS u__id, u.status AS u__status, u.role AS u__role, u.username AS u__username, u.password AS u__password, u.email AS u__email, u.im AS u__im, u.lastlogin AS u__lastlogin, u.ballance AS u__ballance, u.created_at AS u__created_at, u.updated_at AS u__updated_at FROM users u WHERE u.id = ? LIMIT 1
array(1) { [0]=> string(1) "1" }
fetch [0.000094]
SELECT u.id AS u__id, u.status AS u__status, u.role AS u__role, u.username AS u__username, u.password AS u__password, u.email AS u__email, u.im AS u__im, u.lastlogin AS u__lastlogin, u.ballance AS u__ballance, u.created_at AS u__created_at, u.updated_at AS u__updated_at FROM users u WHERE u.id = ? LIMIT 1
fetch [0.000075]
SELECT u.id AS u__id, u.status AS u__status, u.role AS u__role, u.username AS u__username, u.password AS u__password, u.email AS u__email, u.im AS u__im, u.lastlogin AS u__lastlogin, u.ballance AS u__ballance, u.created_at AS u__created_at, u.updated_at AS u__updated_at FROM users u WHERE u.id = ? LIMIT 1
 
Total time : 0.00414180755615

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 63

Мар 8

Doctrine Pagination – Постраничная разбивка средствами Doctrine

Posted on Воскресенье, марта 8, 2009 in Doctrine, php, ZendFramework, Новости

В ZendFramework конечно есть модуль Pagination, но после его использования я решил поглядеть а что есть у Doctrine и нужно сказать что у нее это ЕСТЬ и реализованно неплохо!

Оригинальное описание находится тут: http://www.doctrine-project.org/documentation/manual/1_0/en/utilities#pagination

Пример использования:

1. В контроллере пишем:

$currentPage=$this->_getParam("pager"); // Номер страницы из роутера
$resultsPerPage=20; // Cколько результатор на одной странице
$pager_layout = new Doctrine_Pager_Layout (
	new Doctrine_Pager (
 	  Doctrine_Query :: create ()
 	   	  ->from ( "Users u" )
 	   	  ->orderBy ( "id DESC" ),
 	   	   	  $currentPage ,
 	   	   	  $resultsPerPage
 	),
 	new Doctrine_Pager_Range_Sliding ( 
             array ( "chunk" => 5 )),
	      "/admin/users/index/{%page_number}"
	);
 
$pager_layout ->setTemplate ('<a href="{%url}" class="pager">{%page}</a> ');
$pager_layout ->setSelectedTemplate ('<b class="pager">{%page}</b> ');
$pager = $pager_layout ->getPager ();
$users = $pager->execute();
 
$this->view->pager = "Page: ".$pager_layout ->display('',true)." Total items: <b>".$pager->getNumResults()."</b>";

2. В роутере пропишем:

$router->addRoute('amdinUsers',
  new Zend_Controller_Router_Route('admin/users/index/:pager', 
    array('module' => 'admin', 'controller' => 'users', 'action' => 'index', 'pager' => '1')
  ));

3. В виеве соответственно ловим:

<div class="pager_box"><?php echo $this->pager ?></div>

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 172

Янв 24

Doctrine ORM for PHP Новая документация

Posted on Суббота, января 24, 2009 in Doctrine, Новости

Вчера была выложена новая, переработанная документация по Doctrine, имя ей «Doctrine ORM for PHP». Вся документация была переписана, исправлена и добавлена и доступна по адресу: http://www.doctrine-project.org/documentation/manual/1_0/en

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 250

Дек 16

Doctrine – Двойная доза

Posted on Вторник, декабря 16, 2008 in Doctrine, Новости

Вышло сразу два обновления, обновились до версий 1.0.5 и бета 1.1. Смотреть и качать тут.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 43

Дек 15

Doctrine & ZF Cheat Sheet

Posted on Понедельник, декабря 15, 2008 in Doctrine, ZendFramework

Тут я приведу несколько часто используемых мной приемов для работы с Doctrine и (или) ZF.

1. Выбока по id с проверкой на существование записи:

$courier = Doctrine::getTable("Couriers")->find($this->_getParam('id'));
if ($courier===FALSE) throw new Exception("courierId не найден");
$this->view->courier=$courier->toArray();


Теперь по строкам:

  1. Выбираем из модели Couriers запись с id который нам передал Zend Framework через Router в параметр id.
  2. Если запись не найденна но генерим новое исключение.
  3. Передаем «виеву» массив данных от записи.

2. Сбор все related записей у модели

Как неидеальный пример:

$query = new Doctrine_Query();
$query->from('CityAddress ca,ca.CityStreets cs,cs.CityRegions cr')
         >where("id=?",intval($id) );
$result = $query->execute( array(),Doctrine::HYDRATE_ARRAY );


Что вернет нам не только запись но и все «привязанные» записи (hasOne, hasMany)

3. NOW()
Вернуть текущее время и дату

$messages->date_delivery=new Doctrine_Expression('NOW()');

4. Last Insert ID
Вернуть последний добавленный ID записи

$lastInsertedId=$model->getIncremented();

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Уникальных посетителей темы: 98