ZendFramework

Пример использования Sphinx и Lucene на ZF для разбора почты

Posted in Development, PHP, Sphinx Search, ZendFramework on August 20th, 2009 by Yaroslav Vorozhko – Be the first to comment

Vikram Vaswani написал замечательный пост о том как используя Sphinx, Zend Framework и Lucene, создать поиск по почтовым сообщениям.

В статье рассказывается об основах использования Sphinx и Lucene, а также об основах разбора почтовых сообщений.  В качестве примера Vikram создает консольное приложение для индексации почты и для поиска по ней используя сначала Lucene, а потом и Sphinx.

В общем статья является хорошим примером как используя Sphinx и Lucene быстро сделать поисковик.

Если вы интересуетесь поисковыми движками, то наряду с Sphinx стоит обратить внимание на Solr.

Настраиваем Zend Application

Posted in Development, PHP, ZendFramework on August 13th, 2009 by Yaroslav Vorozhko – 2 Comments

С выходом Zend Framework 1.8 связано много новых изменений и дополнений. Самые значительные это добавление Zend_Application и Zend_Tool.

Zend_Tool представляет собой консольную программу управления проектами на Zend Framework.

Zend_Application это новая система загрузки приложения и конфигурирования проекта.

Рассмотрим как работать с Zend_Application подробнее.

Управление загрузкой приложения занимается Zend_Application_Bootstrap, он выполняет загрузку конфига, инициализацию компонентов, front контроллера, базы данных и объекта вида view.

Большинство настроек этих компонентов может храниться в конфигурационном файле, что обеспечивает дополнительную гибкость и модульность.

Я не буду подробно описывать все файлы и параметры в деталях, так как они уже имеют хорошее описание в manual и руководстве quickstart. Вместо этого, создадим простое рабочее приложение с минимальным количеством настроек.

Вы можете просто использовать copy-past приведенных скриптов, чтоб сэкономить время.

Давате создадим файловую структуру.

PHP:
  1. mkdir -p public/css
  2. mkdir -p public/img
  3. mkdir -p public/js
  4. mkdir -p application/configs
  5. mkdir -p application/controllers
  6. mkdir -p application/layouts/scripts
  7. mkdir -p application/models
  8. mkdir -p application/views/helpers
  9. mkdir -p application/views/scripts/index
  10. mkdir -p application/views/scripts/error
  11. mkdir -p data/session
  12. mkdir -p bin
  13. mkdir -p library/App
  14. mkdir -p tests/application
  15. mkdir -p tests/application/controllers

Теперь скачайте последний релиз ZF и скопируйте директорию Zend в library.

Public каталог

Создайте файл public/.htaccess

PHP:
  1. SetEnv APPLICATION_ENV development
  2.  
  3. RewriteEngine On
  4. RewriteCond %{REQUEST_FILENAME} -s [OR]
  5. RewriteCond %{REQUEST_FILENAME} -l [OR]
  6. RewriteCond %{REQUEST_FILENAME} -d
  7. RewriteRule ^.*$ - [NC,L]
  8. RewriteRule ^.*$ index.php [NC,L]

В файле public/index.php мы просто установим переменные окружения, а все остальное сделает Zend_Application. Как я упоминал раньше, большинство настроек хранится в конфиграционном файле.

public/index.php

PHP:
  1. <?php
  2. define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
  3. define('APPLICATION_PATH', BASE_PATH . '/application');
  4.  
  5. // Include path
  6.     BASE_PATH . '/library'
  7.     . PATH_SEPARATOR . get_include_path()
  8. );
  9.  
  10. // Define application environment
  11. defined('APPLICATION_ENV')
  12.     || define('APPLICATION_ENV',
  13.               (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
  14.                                          : 'production'));
  15.  
  16. // Zend_Application
  17. require_once 'Zend/Application.php';
  18.  
  19. $application = new Zend_Application(
  20.     APPLICATION_ENV,
  21.     APPLICATION_PATH . '/configs/application.ini'
  22. );
  23.  
  24. $application->bootstrap();
  25. $application->run();

Конфигурационный файл

application/configs/application.ini: В моем приложении используется 3 базы данных: основная база, база для разработки и база для тестирования, поэтому определение настроек баз данных разделено на 3 разных части.

PHP:
  1. [production]
  2.  
  3. # Debug output
  4. phpSettings.display_startup_errors = 0
  5. phpSettings.display_errors = 0
  6.  
  7. # Include path
  8. includePaths.library = APPLICATION_PATH "/../library"
  9.  
  10. # Bootstrap
  11. bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
  12. bootstrap.class = "Bootstrap"
  13.  
  14. # Front Controller
  15. resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
  16. resources.frontController.env = APPLICATION_ENV
  17.  
  18. # Layout
  19. resources.layout.layout = "layout"
  20. resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
  21.  
  22. # Views
  23. resources.view.encoding = "UTF-8"
  24. resources.view.basePath = APPLICATION_PATH "/views/"
  25.  
  26. # Database
  27. resources.db.adapter = "pdo_mysql"
  28. resources.db.params.host = "localhost"
  29. resources.db.params.username = "myproject"
  30. resources.db.params.password = "myproject"
  31. resources.db.params.dbname = "myproject_production"
  32. resources.db.isDefaultTableAdapter = true
  33.  
  34. # Session
  35. resources.session.save_path = APPLICATION_PATH "/../data/session"
  36. resources.session.remember_me_seconds = 864000
  37.  
  38. [testing : production]
  39.  
  40. # Debug output
  41. phpSettings.display_startup_errors = 1
  42. phpSettings.display_errors = 1
  43.  
  44. # Database
  45. resources.db.params.dbname = "myproject_testing"
  46.  
  47. [development : production]
  48.  
  49. # Debug output
  50. phpSettings.display_startup_errors = 1
  51. phpSettings.display_errors = 1
  52.  
  53. # Database
  54. resources.db.params.dbname = "myproject_development"

Загрузчик

application/Bootstrap.php: как определено в конфигурационном файле, приложение использует этот файл для процесса загрузки. Я предоставил Zend_Application выполнить всю инициализацию самостоятельно за исключение вида view. В view я хочу установить особый doctype XHTML.

PHP:
  1. <?php
  2. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  3. {
  4.     protected function _initView()
  5.     {
  6.         // Initialize view
  7.         $view = new Zend_View();
  8.         $view->doctype('XHTML1_STRICT');
  9.         $view->headTitle('My Project');
  10.         $view->env = APPLICATION_ENV;
  11.  
  12.         // Add it to the ViewRenderer
  13.         $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
  14.             'ViewRenderer'
  15.         );
  16.         $viewRenderer->setView($view);
  17.  
  18.         // Return it, so that it can be stored by the bootstrap
  19.         return $view;
  20.     }
  21. }

Готово. Это и есть процесс загрузки. Ваше приложение теперь готово использовать ZF MVC и базу данных. Поэтому, давайте продолжим настроку специфических элементов приложения.

Добавим layout

Давайте добвим layout по умолчанию applicaiton/layouts/scripts/layout.phtml:

PHP:
  1. <?php echo $this->doctype() ?>
  2. <html>
  3. <head>
  4.     <?php echo $this->headTitle() ?>
  5.     <?php echo $this->headLink() ?>
  6.     <?php echo $this->headStyle() ?>
  7.     <?php echo $this->headScript() ?>
  8. </head>
  9. <body>
  10.     <?php echo $this->layout()->content ?>
  11. </body>
  12. </html>

Добавим контроллер и вид view

application/controllers/IndexController.php ничего особенного в нем:

PHP:
  1. <?php
  2. class IndexController extends Zend_Controller_Action
  3. {
  4.     public function indexAction()
  5.     {
  6.     }
  7. }

Дабавим view для index/index action в application/view/scripts/index/index.phtml

PHP:
  1. <h1 id="welcome-to-the-zend-framework">Welcome to the Zend Framework!</h1>

application/controllers/ErrorController.php вызывается в том случае, если запрашиваемый контроллер не был найден. В зависимости от переменных окружения он вызывает исключение и вывод трассировки стека.

application/controllers/ErrorController.php:

PHP:
  1. <?php
  2. class ErrorController extends Zend_Controller_Action
  3. {
  4.     public function errorAction()
  5.     {
  6.         $errors = $this->_getParam('error_handler');
  7.  
  8.         switch ($errors->type) {
  9.             case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  10.             case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  11.  
  12.                 // 404 error -- controller or action not found
  13.                 $this->getResponse()->setHttpResponseCode(404);
  14.                 $this->view->message = 'Page not found';
  15.                 break;
  16.             default:
  17.                 // application error
  18.                 $this->getResponse()->setHttpResponseCode(500);
  19.                 $this->view->message = 'Application error';
  20.                 break;
  21.         }
  22.  
  23.         $this->view->exception = $errors->exception;
  24.         $this->view->request   = $errors->request;
  25.     }
  26. }

И принадлежащий ему вид:

PHP:
  1. <h1 id="an-error-occurred">An error occurred</h1>
  2. <h3 id=""><?php echo $this->message ?></h3>
  3.  
  4. <? if ('development' == $this->env): ?>
  5.  
  6.     <h4 id="exception-information">Exception information:</h4>
  7.     <p>
  8.       <strong>Message:</strong> <?php echo $this->exception->getMessage(); ?>
  9.     </p>
  10.  
  11.     <h4 id="stack-trace">Stack trace:</h4>
  12.     <pre><?php echo $this->exception->getTraceAsString() ?></pre>
  13.  
  14.     <h4 id="request-parameters">Request Parameters:</h4>
  15.     <? var_dump($this->request->getParams()); ?>
  16.  
  17. <? endif; ?>

Теперь ваше приложение должно работать. Попробуйте открыть / и /foo. Вы должны будете увидеть index/index и error/error actions.

Сокращено и переведено из mafflog.

Прикручиваем свои сообщения к Zend Validate Email

Posted in Development, PHP, ZendFramework on August 11th, 2009 by Yaroslav Vorozhko – Be the first to comment

Валидацией email адресов в ZF занимается Zend_Validate_Email. Кто не знает, email состоит из двух частей, имени и хоста. Хост проверяется с помощью Zend_Validate_Hostname и все эти вещи выполняются в background, т.е. мы не получем каких либо нотификаций о происходящих там процессах.

Так, вот Thomas Weidner разобрался с этой проблемой и предлагает свое решение валидиции email.

Zend Mail как вложить изображение в письмо

Posted in Tips And Tricks, ZendFramework on August 11th, 2009 by Yaroslav Vorozhko – Be the first to comment

Есть два варианта добавить картинку в почтовое html сообщение.
1. Использовать удаленный сервер для загрузки сообщения.
2. Вложить сообщение в письмо и ссылаться на него в html документе.
Первый способ очень простой и не требует программирования:

PHP:
  1. <img src="http://somededicateserver.com/images/logo.gif" />

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

PHP:
  1. $html = $this->_request->getParam('html','');//в html у нас храниться исходный HTML код сообщения
  2. $mail = new Zend_Mail('UTF-8');
  3. //убедитесь, что файл существует и доступен для чтения
  4. $filename = '/path/htdocs/img/logo.gif';
  5. if (is_readable($filename)) {
  6.   $mail->setType(Zend_Mime::MULTIPART_RELATED);   
  7.   $at = $mail->createAttachment(file_get_contents($filename))
  8.   $at->type = 'image/gif'
  9.   $at->disposition = Zend_Mime::DISPOSITION_INLINE
  10.   $at->encoding = Zend_Mime::ENCODING_BASE64
  11.   $at->id = 'cid_' . md5_file($filename);
  12.   $html = str_replace('file://attached_image''cid:' . $at->id$html);   
  13. }
  14. $mail->setBodyHtml($html, 'UTF-8', Zend_Mime::ENCODING_8BIT);

Внутри html сообщения у нас есть специальная строка (file://attached_image), ссылка на изображение:

PHP:
  1. <img src="file://attached_image" />

которая, после обработки, будет заменена на вложенное в письмо изображение, и будет иметь следующий вид:

PHP:
  1. <img src="cid:cid_4b3fdb60e9422ce97926cc8d3b601188" />

Все, отправляем письмо и проверяем результат.

Как установить кодировку по умолчанию для Zend View ?

Posted in Tips And Tricks, ZendFramework on July 30th, 2009 by Yaroslav Vorozhko – 2 Comments

Как установить кодировку по умолчанию для Zend View ?

Первый способ, если вы используете Zend_Application:
В application.ini:
resources.view.encoding = "ISO-8859-1"

И второй вы можете вручную установить ее для объекта Zend_View:
$view = new Zend_View();
$view->setEncoding("ISO-8859-1");
$viewRenderer =
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view);

ZF FAQ: установка кодировки при подключении к БД

Posted in Tips And Tricks, ZendFramework on July 28th, 2009 by Yaroslav Vorozhko – Be the first to comment

Привет!
Вопрос: Как установить кодировку utf8 при подключении к базе данных?

В версии Zend Framework 1.8, если вы используете Zend_Application, кодировка устанавливается через конфигурационный файл.

PHP:
  1. [production]
  2. resources.db.adapter = "pdo_mysql"
  3. resources.db.params.host = "localhost"
  4. resources.db.params.username = "YOURUSER"
  5. resources.db.params.password = "YOURPASS"
  6. resources.db.params.dbname = "YOURDB"
  7. resources.db.params.charset = utf8
  8. resources.db.isDefaultTableAdapter = true

В версии 1.7, кодировку можно установить при явном подключении к БД или при использовании конфигурационного файла, ниже приведен пример как установить кодировку явно.

PHP:
  1. $config = Zend_Registry::get('dbConfig');
  2.  
  3. $db = Zend_Db::factory($config->db->adapter, $config->db->config->toArray());
  4. Zend_Db_Table::setDefaultAdapter($db);
  5. Zend_Registry::getInstance()->set('db', $db);
  6.        
  7. $db->query("set names utf8");
  8. $db->query("set time_zone = '+0:00'");

ZF FAQ: Минимальный bootstrap.php

Posted in Tips And Tricks, ZendFramework on July 27th, 2009 by Yaroslav Vorozhko – Be the first to comment

Сегодня открываю в своем блоге раздел Zend Framework FAQ. Куда соотвественно буду писать различные вопросы-ответы по теме программирования в Zend Framework.

Итак, вопрос:

Каким должен быть минимальный bootstrap.php?

Ответ:

Создайте файл application/Bootstrap.php

и его содержимое как минимум должно быть таким:

PHP:
  1. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
  2. {
  3. }

Класс Bootstrap появился с версией 1.8. Поэтому при переходе с 1.7 на 1.8 учтитывайте это.