За чистый и ясный код!

Статьи на тему программирования под веб, используя PHP, MySQL, Jquery и многое другое
Просмотр категории - ZendFramework

Как изменить цвет консоли в ZF2

Март23
Собрался в поход в горы, в лес, на байдарках? Для надежной связи советую использовать пыле / влагозащищенный телефон Runbo X5

Вывод данных, поиск решения

В последнее время я работаю на большом проекте и переписываю часть его ядра. Т.е. никакого UI я не вижу, все что я пишу запускается из командной строки. Соответственно вся техническая информация которая выводится в командную строку отображается в таком сероватом цвете, в цвете по-умолчанию. Информации много, я уже разделил её на блоки, обрамив каждый скобками, квадратными, фигурными, обычными…, но всё это не то. Нужно чтобы инфа выводилось в цвете, чтобы глаз сразу видел, что если красный цвет я вывожу, то где-то, скажем поломка, если желтый, то внимание ну и тд.
Занялся я этим вопросом, начал изучать как устроен терминал, какие последовательности команд надо ему подать, чтобы выводимая инфа была в определенном месте, в определенном цвете. Пишу я свою часть на ZF2 и я случайно там обнаружил, что есть классы которые реализованы для отображения данных в цвете, как для ОС семейства Линукс, так и Виндовс. Все решается очень просто!

Небольшой пример кода, который выводи инфу в цвете:

// Подключаем необходимые библиотеки
use Zend\Console\Console as Console;
use Zend\Console\ColorInterface as Color;

//где-то, где вам надо просто используем классы, вывод строки с данными
Console::getInstance()->write("  " . str_pad($i,6) . '- (') .Console::getInstance()->write(str_pad($percent,5), Color::LIGHT_CYAN) . Console::getInstance()->write('% (') . Console::getInstance()->write($countVendorHotelsOst, Color::LIGHT_MAGENTA) . Console::getInstance()->write(') w-') . Console::getInstance()->write(str_pad($weight,3), $weight < 100 ? Color::LIGHT_YELLOW : Color::YELLOW) . Console::getInstance()->write(') - ' . str_pad($vendorHotel->hotelCode . ' ', 40,'-') . '-> ' . $idHotel);

// новая строка
Console::getInstance()->writeLine();

В итоге получаю такую картинку

Вывод цветных данных скрипта в командную строку

А вот как было без использования специальных классов:

Вывод данных скрипта в командную строку

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

Что еще позволяют сделать эти классы

Позволяет работать с адаптерами терминалов
— Posix
— Virtual
— Windows
— Windows Ansicon

Работает с кодировками
— UTF-8
— UTF-8 Heavy
— ASCII
ASCII Extended (расширенная)
DECSG

Позволяет выводить данные
— в строку, друг за другом
— в строку с переводом на новую
— устанавливать цвет текста
— устанавливать цвет фона
— выводить данные в определенное место в консоли
— прятать/показывать курсор при работе скрипта
— очищать экран
— получать различные данные о консоли

Еще фишка этих классов по работе с консолью, они позволяют ждать ввода инфы при работающем скрипте, т.е. в консоле возможен диалог скрипта с разработчиком.

С такими возможностями есть шансы, что скоро кто-то напишет велосипед, аля FAR или MC на PHP.

ЗЫ Я нашел еще кучу классов, для работы с цветом, ссылки ниже.

ANSI Escape sequences
Как подключить вывод цвета в терминале Windows
PHP CLI Colors

Статья просмотренна 386024 раз, зашло посетителей 25903

Кеширование запросов DESCRIBE при работе с моделями в Zend Framework

Март5

Добрый всем день!

Если вы пишите свой сайты с использованием ZendFramework и при этом используете модели для работы с БД, то вы должны знать, что сам фреймворк первым запросом будет получать информации о таблицы с которой работает:

DESCRIBE `table_name`;

следовательно каждый раз фреймворк делает чтение её структуры, что приводит к лишнему запросу и когда таблиц много или посетителей ресурса — тормозам.

На самой странице документации к зенду описана такая ситуация.

Я создал абстрактный класс от которого должны наследоваться все мои модели, назвал его AbstractTableModel, вот его код:

<?php
/**
 * Class fot caching describe table query
 *
 * @filesource
 * @author maxnag
 */
abstract class AbstractTableModel extends Zend_Db_Table_Abstract
{
	public function __construct($config = array())
	{
		parent::__construct($config);
		
		if (Zend_Db_Table_Abstract::getDefaultMetadataCache() === null)
		{
			$frontendOptions = array('automatic_serialization' => true);

			$zendCacheDir = './cache/'; // directory for caching

			if (!file_exists($zendCacheDir))
			{
				mkdir($zendCacheDir, 0777);
			}

			$backendOptions  = array('cache_dir' => $zendCacheDir);

			$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
			Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
		}
	}
}

В корне проекте будет создаваться папка cache и в ней будет храниться описание затронутых таблиц, зенд сам следит за временем кеша, единственное я после изменения структуры таблицы удаляю весь кеш, дабы все шло гладко.

Удачи, Максим.

Статья просмотренна 76771 раз, зашло посетителей 11494

Работа с Zend_Session

Июнь10

Всем привет! В статье будет рассмотрено работа с сессией средствами ZendFramework.

Простейшая работ с сессией

$sess = new Zend_Session_Namespace('MyNS');

MyNS– название пространства имен, должно быть не NULL, не должен нач. с цифры и _
Если пространство имен не задано, то по умолчанию Default

Данная конструкция аналогична

$_SESSION[‘MyNS’]

Добавления данных в сессию:

$sess->someData = 'some info';    аналог $_SESSION['MyNS']['someData'] = 'some info'; 

Получение название пространства имен:

$sess->getNamespace();

Доступны магические методы

__isset(), __unset(), __get(), __set()

Расширенная работа сессий

Время жизни пространства имен

$sess = new Zend_Session_Namespace('MyNS');
$sess->someData = 'some info';

$sess->setExpirationSeconds(5, 'someData'); - время жизни ключа someData будет 5 сек
$sess->setExpirationSeconds(3); - время жизни пространства имен Dialog будет 3 сек

$sess->setExpirationHops(5 , 'someData');  - через 5 успешных обращений к ПИ (NS) someData будет удалена
$sess->setExpirationHops(3); - через 3 «прыжка» всё ПИ будет удалено

Работа с массивами в пространствах имен

$sess = new Zend_Session_Namespace('MyNS');
$sess->array = array();
$sess->array['testKey'] = 1; // Не работает в версиях ниже PHP 5.2.1

Хранение сессии в БД

Если Вы используете высоко нагруженное веб-приложение и у вас стоит несколько серверов и есть аппаратные/программные средства по контролю за нагрузкой, то каждая страница может обрабатывать разные сервера, вспомним сайт Одноклассники. Из-за этого файл сессии может быть недоступен. Для устранения такой проблемы можно использовать хранение сессии в БД.
Вообще PHP позволяет переопределить место хранения сессии, переопределить ф-ции которые отвечают за открытие, закрытие, запись и тд сессии, за это отвечает ф-ция session_set_save_handler

Вот пример использования сессии средствами Зенда:

Создаем таблицу в БД
CREATE TABLE `session` (
  `id` char(32),
  `modified` int,
  `lifetime` int,
  `data` text,
  PRIMARY KEY (`id`)
);

настраиваем Zend:

$db = DbManager::getInstance(); // тут получения объекта подключения к БД (у каждого может быть свой)
Zend_Db_Table_Abstract::setDefaultAdapter($db);

$config = array(
    'name'           => 'session',
    'primary'        => 'id',
    'modifiedColumn' => 'modified',
    'dataColumn'     => 'data',
    'lifetimeColumn' => 'lifetime'
);
 
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
 
Zend_Session::start();

// дальнейшая работа с сессией

Статья просмотренна 34190 раз, зашло посетителей 8254

Сайт упал из-за ECHO

Март4
Дидактические материалы по геометрии Гусев 8 класс.

Привет, уважаемые читатели!

В данной статье я хотел описать решение проблемы с которой я столкнулся, на решение проблемы у меня ушло три часа, вот я не хочу, чтобы мои читатели не тратили так много времени.

Также данная статься предназначена для людей которые имеют представление об ООП, приведениях типов, в общем, с углубленным знанием PHP.

Итак. Я работаю с ZendFramework. В одном из проектов который я создаю было задача построения не простой формы, следовательно вывести во вьюхе:

<?php echo $this->form;?>

я не смог из-за сложной верстки (декорировать на зенде — дольше, чем на голом ХТМЛе создать), я просто разобрал созданную в контроллере форму по элементам:

$itemsList = $this->form->getElements ();

в таком виде я получил массив всех элементов, ключами массива служили название полей в форме, а значение — объект данного поля (валидаторы, декораторы и тд).

При построении кнопок в данной форме я воспользовался конструкцией тернарного оператора:

<?php echo isset($itemsList["submit"]) ? $itemsList["submit"] : ''?>
<?php echo isset($itemsList["reset"])  ? $itemsList["reset"] : ''?>

В форме при разных условиях часть кнопок отсутствовала, поэтому юзал условия.

При такой конструкции сайт ВАЛИТСЯ!!! Никаких сообщений нет, трейса нет, в логе-апача ничего нет — полный ГОЛЯК! Нашел я эту проблему методом «научного тыка».

Ну как ни у кого нет мысли почему эти строки валили сайт, еще скажу, если выводить какую-то одну из строк — все ОК?!

В общем дело в том, что именно оператор ECHO виновен, он не смог преобразовать объект в строку и выдать её, при этом никакого предупреждения не выдав!!!!!!!!

Если переписать эти строки вот так:

<?php print isset($itemsList["submit"]) ? $itemsList["submit"] : ''?>
<?php print isset($itemsList["reset"])  ? $itemsList["reset"] : ''?>

, т.е. заменить echo на print все нормально срабатывало.

Как бы я не крутил конструкция с эхо, скобочки разные, короткое сокращение эхо, и тд ничего не происходило. Помогло только явное приведение к строке с помощью конструкции (string), или конкатенация с пустой строкой, или приведение к типу с помощью ООП метода __toString();

<?php echo isset($itemsList["submit"]) ? (string)$itemsList["submit"] : ''?>
<?php echo isset($itemsList["reset"])  ? (string)$itemsList["reset"] : ''?>
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"].' ' : ''?>
<?php echo isset($itemsList["reset"])  ? $itemsList["reset"].' ' : ''?>
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"]->__toString() : ''?>
<?php echo isset($itemsList["reset"])  ? $itemsList["reset"]->__toString() : ''?>

Но самое, что для меня не понятное, почему если, я расписал условие в полном объеме:

if(isset($itemsList["submit"]))
{
	echo  $itemsList ["submit"];
}

if(isset($itemsList["reset"]))
{
	echo  $itemsList ["reset"];
}

все выполняется, заметьте, преобразованием типа я не занимался!!!

Вот часть кодов, может кто хочет протестировать:
Класс формы

public function __construct($options = null)
{
.....
	$this->_options = $options;
.....
}

public function init()
{
.....
	$this->addElement(
		'submit', 
		'submit', 
		array(
			'label' => 'submit', 
			'class' => 'but', 
			'decorators' => array('ViewHelper'), 
			'title'=>'submit'
		)
	);

	$this->addElement(
			'submit',
			'reset',
			array(
					'label'=>'reset',
					'class' => 'but',
					'decorators' => array('ViewHelper'),
					'title'=>'reset'
			)
	);
.....
}

protected $_options = array();

Контроллер

$form = new Module_Forms_MyForm(array('some options'));
.....
$this->view->form = $form;

Вьюха

$itemsList = $this->form->getElements ();

<form ....>
.....
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"] : ''?>
<?php echo isset($itemsList["reset"])  ? $itemsList["reset"] : ''?>
.....
</form>

Плиз, оставь свои мнения, почему в тернарном операторе эхо не сработало, а в общем условии — все ок!! Очень интересно знать, отвечу на любые вопросы.

UPD: Забыл сказать, все это без каких либо изменений работет по виндой, но подлинухом не работает!

Статья просмотренна 49895 раз, зашло посетителей 11921

выполнение действий до (preDispatch) и после (postDispatch) действия (Action)

Январь4

Всем привет. В этой статье я хочу поделится с Вами о том как выполнять какие-то действия до/после выполнения действий в методе Action контроллера.

Для чего это может понадобится? Ну например, перед тем как делать действия вам необходимо удостоверится залогинелся пользователь или нет. Конечно можно в каждом методе Action проверять залогинелся ли юзер или нет, но при таких условиях и в зависимости от громоздкости Вашего приложения необходимо это условие прописывать во всех методах, это не удобно, а вдруг Вы решите как-то сменить метод проверки на залогиненность, что тогда? Переписывание всех условия. Для решения данной задачи, можно создать контроллер который будет наследоваться от Zend_Controller_Action и в этом контроллере будет метод preDispatch или postDispatch которые будут делать действия до или после выполнения действий в самом экшене.

class BaseController extends Zend_Controller_Action
{
	/**
	* Pre-dispatch routines
	*
	* (non-PHPdoc)
	* @see Site/branch/Lib/Zend/Controller/Zend_Controller_Action#preDispatch()
	*/
	public function preDispatch()
	{
		$auth = Zend_Auth::getInstance();
		$userAuth = $auth->getStorage()->read();

		if (isset($userAuth->Id))
		{
			$this->_redirect('/');
		}
	}
}

class Module_IndexController extends BaseController
{
	public function indexAction()
	{
		// какие-то свои действия
	}
}

такие же работает и метод postDispatch.

Дешевая техника в интернет-магазине http://bestchinashops.ru/chinabuye/

Есть еще:

метод init() — этот метод выполняет действия вообще до метода preDispatch.

метод Render() — этот метод рисует данные вьюхи.

более подробно о всех методах вот тут — Контроллеры действий

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

позиция метод
1 __construct
2 init
3 preDispatch
4 indexAction
5 postDispatch

Именно в такой последовательности запускаются методы. Юзайте на здоровье.

Статья просмотренна 28989 раз, зашло посетителей 6499

  

Облако тегов

cli csv dump events form Kohana locale models MySQL mysqldump orm PHP tools trigger validate газ газовый счетчик итоги кеширование переменные

Облако тегов плагина WP Cumulus для WordPress требует для просмотра Flash Player 9 или выше.

Я на твиттере!

  • у твиттера тоже бывают перерывы...

Календарь

Ноябрь 2017
Пн Вт Ср Чт Пт Сб Вс
« Июл    
 12345
6789101112
13141516171819
20212223242526
27282930  

Сейчас на сайте