RSS Записей | RSS Комментариев
Мой путь наверх / DoFollow блог - Нас невозможно сбить с пути — нам всё равно куда идти. Интернет, как источник дохода

Мой путь наверх / DoFollow блог

RSS Записей RSS Комментариев Карта сайта

Нас невозможно сбить с пути — нам всё равно куда идти. Интернет, как источник дохода

Архив ‘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 человек, легко идут на контакт, так что велком.

MongoDB, хранение файлов в базе

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

В интернетах бытует мнение, что хранить файлы в БД — школоло. Разрушаем стереотип с Mongo GridFS.

Введение:
MongoDB предоставляет возможность хранить файлы любого размера в Mongo GridFS
Для драйвера PHP — это обычная коллекция, в которой есть поле для хранения бинарных данных.
Бинарные данные в свою очередь разбиваются на чунки(небольшие куски).
Бинарные данные можно извлечь как целиком, так и почунково(это экономит память).

Плюсы хранения данных в БД MongoDB:
MongoDB может хранить миллионы файлов в БД, хранение такого объёма данных в файловой системе может вызвать проблемы(начиная с IO проблем, заканчивая проблемами доступа к данным из разных серверов).
MongoDB реплицирует данные на все сервера, что упрощает доступ к данным на отдельно взятом сервере.
Нет проблем с бекапами и целостностью данных на разных серверах. надёжность обеспечивается MongoDB.
К загруженному файлу можно прикрепить метаданные (описание, комментарии, лайки, и.т.д.)
Т.к. файлы хранятся в чунках — можно работать с любой частью файла.

Минусы:
Быстродействие ниже, чем nginx + файловая истема. Сравним:
nginx + файловая система, получаем 6559.31 операций в секунду
apache + файловая система: получаем 2625.37 операций в секунду
nginx + модуль nginx-gridfs, получаем 1083.88 операций в секунду

Вывод: nginx + fs на высоте, но это решение не даёт масштабируемости и гибкости.
nginx + nginx-gridfs даёт приличные результаты, которые существенно возрастут, при использовании нескольких серверов MongoDB.

Благодарность, http://tokarchuk.ru за тесты.

MongoDB, найти уникальные значения

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

Задача: найти уникальные значения определённого поля документов коллекции.

Пример:

Создадим документы

db.comments.save({"user": {"points": 25}})
db.comments.save({"user": {"points": 31}})
db.comments.save({"user": {"points": 25}})

Решение:

db.comments.distinct("user.points");
[ 25, 31 ]

Решение на PHP:

$points=$this->mongo_base->command(array("distinct" => "comments", "key" => "user.points"));

Думаю, что это map-reduce, следовательно индексы не юзаются. Если коллекция большая — лучше эти элементы дублировать в другую коллекцию, или, подправить модель предметной области, сократив подобные запросы к минимуму.

Проверяй плагины и темы любимого WordPress, перед вставкой на сайт.

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

Думаю читателям будет интересно, что IAD, кроме того, чтобы постить лыбдыбры, кое-что сделал для улучшения экологии планеты сайтостроителей.

Напоминаю, что есть uneval.com — мой сервис проверки PHP кода на вредоносные конструкции.

А теперь 5 копеек, почему не следует вставлять свеже-скачанный PHP код(тему, плагин, и.т.д.) сразу на сайт:

1. Там может быть бэкдор(PHP код дающий полноценный shell на ваш сервер, хостинг, VDS). Получив такой доступ можно просмотреть, изменить(если права позволяют) любой файл сайта. И файлы других Ваших сайтов. Это позволит использовать Ваши сайты в своих целях, или просто сломать их, или поместить мелкую трудно-отлавливаемую ошибку, изведя жертву до нервного срыва. =)

2. Разместить код в тему сайта, который будет отображать ссылки только поисковым роботам(клоакинг). Средства тёмного SEO.

3. Украсть/изменить информацию сайта.

Ранее писал о безопасности: Бэкдор с триггерах субд, WordPress, eval.
В общем, юзайте мой сервис uneval.com

CodeIgniter + MongoDB + NetBeans 7.0. Mongo() class code completion.

декабря 12, 2011 | Комментариев нет

Многобуков. Всё под катом.

Читать полностью »

Google Reader, работаем из PHP

декабря 7, 2011 | Комментариев нет

Качаем ericmann-gReader-Library с гитхаба.

Сразу проезжаемся рубанком, заменяя private на protected, иначе нельзя обратиться к методам и свойствам при расширении класса extends.

Задача: вытянуть из Google Reader записи, отмеченные звёздочками (starred) и отослать информацию о снятии звёздочки

Решение, расширяем базовый класс двумя методами:

include_once 'ericmann-gReader-Library/greader.class.php';
 
class google_reader extends JDMReader
{
	public function __construct() 
	{
 
	}
 
	public function connect($username, $password)
	{
		parent::__construct($username, $password);
	}
 
	// List a particular number of unread posts from the user's reading list
	public function getStarred($limit) {
		$gUrl = 'http://www.google.com/reader/api/0/stream/contents/user/-/state/com.google/starred';
		$args = sprintf('n=%2$s&ck=%3$s&client=GoogleReaderDashboard', time() - (7*24*3600), $limit, time());
 
		$data = $this->_httpGet($gUrl, $args);
 
		$decoded_data = json_decode($data, true);
		$feed_items = $decoded_data['items'];
 
		return($feed_items);
	}
 
	/**
	  * Mark this an item as unstarred
	  *
	  * This method marks an item as unstarred for a certain user.
	  *
	  * @param string $itemId  The item id that can be retrieved from $this->listAll()
	  *
	  * @return boolean
	  */
 
	public function markAsUnstarred($itemId) {
		$data = sprintf(
			'i=%1$s&T=%2$s&r=%3$s&ac=edit', 
			$itemId, $this->_token,'user/-/state/com.google/starred'
		);
 
		$path = '/reader/api/0/edit-tag?client=-';
		$host = 'www.google.com';
 
		$response = $this->_httpPost($host, $path, $data);
		if($response == null) return false;
		return true;
	}
 
}

юзаем:

		$this->load->library('google_reader');
		$this->google_reader->connect('login@gmail.com','******');
 
		if ($this->google_reader->loaded)
		{
			print_r($this->google_reader->getStarred(10));
		}
© 2010 Мой путь наверх / DoFollow блог. Все права защишены.
Powered by Лаборатория Яда. Написать администратору