Создаем видеобиблиотеку с PHPixie

  • Tutorial
image
После моего предыдущего поста о выборе легкого Фреймворка я погуглил и увидел что для некоторых из них нет ни одного русскоязычного туториала. Так вот я решил написать серию постов дабы заполнить эту нишу. Я думаю стоит начать с тех на которых я в конце остановился, а так как для Silex написано уже достаточно много то этот пост будет посвящен PHPixie.

Для тех кто не читал моего сравнения фреймворков, PHPixie — маленький и по моим меркам очень быстрый фреймворк с модульной структурой, хорошо реализованным DI, отсутствием статиков и простой архитектурой.


На официальном сайте все туториалы написаны на примере фей, я же попробую быть оригинальным и мы создадим библиотеку видео из Youtube. То есть мы сможем добавлять, удалять и просматривать видео. А еще по дороге научимся использовать API самого ютуба для получения мета информации и тамбнейлов.

Создание проекта


PHPixie можно установить либо используя Composer, либо скачав снапшот готовой системы с сайта. Разницы почти нет, так как снапшот регулярно обновляется и являет собой базовой проект с проинсталлированными тремя библиотеками (core, db и orm). Для простоты будем использовать второй метод, ссылка на снапшот здесь phpixie.com/phpixie.zip. Сервер надо настроить на папку /web/ внутри проекта. Вот и все, теперь можем зайти на наш хост и увидеть маленькое приветствие.

Объект $pixie


Объект $pixie — это имплементация DI Контейнера и Сервис Локатора, нечто похожее на $app в Silex. Он доступен как проперти контроллера и передается практически в каждый конструктор, $pixie также содержит фактори методы для каждого класса фреймворка. Грамотное использование его позволяет полностью избежать связывания классов а следовательно упростить тестирование. В отличии от Silex добавление методов и проперти в $pixie происходит только путем расширения класса. В базовом проекте уже присутстует класс App\Pixie который наследует от PHPixie\Pixie, как раз в него мы можем добавлять свой код чтобы иметь к нему доступ повсюду. Следует обратить внимание на то что это не синглтон и передавать его между классами приходится явно, такой подход был избран для избежания какого-либо глобального состояния в коде, аналогично фреймворк никогда не использует статические методы. Каждый модуль, например db или orm поставляет свой класс с фактори методами, эти классы прописываются в нашем App\Pixie в $modules. Потом мы можем запрашивать их как проперти, например используя $pixie->db->query() и $pixie->orm->get(), что вносит дополнительную структурированность и позволяет избежать супа из методов. В нашем случае менять в App\Pixie нам ничего не нужно.

База данных


Мы будем использовать лишь одну простенькую табличку для хранение информации о видео, вот ее структура:
CREATE TABLE `videos` (
	`id` INT(10) NOT NULL AUTO_INCREMENT,
	`video_id` VARCHAR(20) NOT NULL,
	`title` VARCHAR(255) NOT NULL,
	PRIMARY KEY (`id`)
);


Теперь прописываем настройки соединения к базе в /assets/config/db.php, например:
return array(
	'default' => array(
		'user'=>'root',
		'password' => '',
		'driver' => 'PDO',
		'connection'=>'mysql:host=localhost;dbname=videos'
	)
);

тут, думаю все достаточно тривиально.

Модель


Любая MVC структура начинается с модели, в нашем случае она только одна, Video. Кто знаком с Kohana сразу почувствует себя дома, для создания модели достаточно просто расширить класс \PHPixie\ORM\Model:
namespace App\Model;
class Video extends \PHPixie\ORM\Model{}

Привязка к таблице по умолчанию происходит следуя из имени класса. В нашем случае так оно и есть и менять ничего не нужно. Доступ к модели можно получить используя $pixie. Самые яркие примеры кода:
//Создание и сохранение
$video = $pixie->get('video');
$video->title = 'Test';
$video->save();

//Поиск
$video = $pixie->get('video')->where('title','Test')->find();

//Поиск всех
$videos = $pixie->get('video')->find_all();


Базовая разметка


В базовом проекте который ми скачали есть в наличии подвид контролера, класс App\Pixie. Его работа сводится к тому чтоб рендерить шаблон main.php доступный как проперти $view. Наши контроллеры просто передают разные данные в этот шаблон, включая $subview — имя подшаблона который надо вставить. Мне как раз очень понравилось то, что логика того как работают мастер-страницы и подшаблоны не прописана в самом фреймворке а выносится в сам проект, что позволяет переделать ее по своему усмотрению. Наш main.php будет выглядеть примерно так:
<!DOCTYPE html>
<html>
	<head>
		<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet"/>
	</head>
	<body>
		<div class="container">
			<div class="row">
				<div class="offset3 span6">
					<h2><a href="/">PHPixie Vids</a></h2>

					<!-- Форма добавления видео -->
					<form class="form-inline" method="post" action="/videos/add">
						<input type="text" placeholder="Paste Link…" name="url">
						<button type="submit" class="btn btn-primary">Add new</button>
					</form>
				</div>
			</div>
			<div class="row">

				<!-- Подключаем подшаблон -->
				<?php include($subview.'.php'); ?>
			</div>
		</div>
	</body>
</html>


Подшаблонов у нас всего два: list.php (для списка добавленных роликов) и view.php (для просмотра выбранного видео). Вот они:
<!-- /assets/views/list.php -->
<div class="offset3 span6">
	<ul class="thumbnails">
		<?php foreach($videos as $video):?>
			<li class="span3">
				<a class="thumbnail" href="/videos/view/<?php echo $video->id; ?>">

					<!-- Вот как легко получить тамбнейл видео по айдишке -->
					<img src="http://img.youtube.com/vi/<?php echo $video->video_id;?>/0.jpg">
					<div class="caption">
						<h3><?php echo $video->title;?></h3>
					</div>
				</a>
			</li>
		<?php endforeach;?>
	</ul>
</div>


<div class="offset3 span6">

	<!-- А вот как вставить видео и включить автопроигрывание-->
	<iframe width="420" height="345" src="http://www.youtube.com/embed/<?php echo $video->video_id; ?>?rel=0&autoplay=1"></iframe>
</div>


Роутинг


Я знаю что вы уже заждались самого кода, но перед тем как мы перейдем к контроллеру нам надо прописать его в /assets/config/routes.php. На самом деле в базовом проекте прописан только один роут и он выглядит как /контроллер/метод/id, что в принципе нас устраивает, но было б очень кстати по менять дефолтный контроллер из Hello на наш Videos.
return array(
	'default' => array('(/<controller>(/<action>(/<id>)))', array(
					// Дефолтные значения
					'controller' => 'Videos',
					'action' => 'index'
					)
				),
);


Контроллер


Поскольку нам нужны 3 страницы в контроллере должно быть 3 метода. Вот с чего мы начнем:
namespace App\Controller;

class Videos extends \App\Page {

	public function action_index(){
		$this->view->subview = 'list';
		$this->view->videos  = $this->pixie->orm->get('video')->find_all();
	}
	
	public function action_add(){
		$this->redirect('/');
		//Об этом чуть позже
	}
	
	public function action_view(){
		$this->view->subview = 'view';

		//Берем id с URL: /video/view/3
		$id = $this->request->param('id');
		$this->view->video = $this->pixie->orm->get('video')
												->where('id', $id)
												->find();
	}
}

Задачи выбора всех и одного видео тривиальны.
Рассмотрим теперь добавление нового видео. Идентификатор видео в ссылке ютуба передается параметром 'v', например www.youtube.com/watch?v=75nBenOWul0, мы можем достать его множеством способов, но наиболее аккуратным мне показался с использованием parse_url(), вот так:
parse_str(parse_url( $url, PHP_URL_QUERY ), $vars );
$video_id = $vars['v']; 

Получить информацию о ролике, в нашем случае его имя, можно используя API по ссылке youtube.com/get_video_info?video_id=<id видео>. Используя эти знания мы теперь можем дописать недостающий action_add():
	public function action_add(){
		if($url = $this->request->post('url')){
			parse_str(parse_url( $url, PHP_URL_QUERY ), $vars );
			$video_id = $vars['v']; 
			$response = file_get_contents("http://youtube.com/get_video_info?video_id=".$video_id);
			parse_str($response, $data);
			$video = $this->pixie->orm->get('video');
			$video->title = $data['title'];
			$video->video_id = $video_id;
			$video->save();
		}
		$this->redirect('/');
	}


И вуаля! Вот кстати скриншот результата:
image

Если вы ожидали более сложного контроллера или конфигурации то их нет, да и самого фреймворка почти не заметно, это и позволяет сконцентрироваться как раз на написании своего кода вместо изучения чужого.
Надеюсь пост вам понравился, а в другой раз мы будем учится писать на Lithium.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 17
  • +1
    Это, я так понял, получения модели App\Model\Video
    $video = $pixie->get('video');

    То есть автомагическим способом она была передана в контейнер с именем, совпадающим с названием класса? Или с именем файла?

    Как будет решена ситуация когда нужно получить \App\Model\Foo\Iddqd и \App\Model\Bar\Iddqd?
    • 0
      Посмотрел сорс, там все просто:

      $model = $this->pixie->app_namespace.'Model\\'.$name;
      $model = new $model($this->pixie);

      то есть в вашем случае будет $pixie->get('Bar\Iddqd');
      • +5
        Не совсем про фреймворк, но вдруг кому пригодится. Ссылки на ролики на ютубе бывают разных видов:

        youtube.com/watch?v=ShPq2Dmy6X8
        youtube.com/embed/ShPq2Dmy6X8
        youtu.be/ShPq2Dmy6X8

        Некоторое время назад решал похожую задачу получения видео с трех основных видеохостингов: RuTube, YouTube, Vimeo, получился такой класс. Йа ссылка

        $v = new VideoThumb($link); //Процессим ссылку
        $v->getVideo(); //Ссылка на видео
        $v->getTitle(); //Название ролика
        $v->fetchImage($to); //Скачать самое большое превью ролика в файл $to
        
        • 0
          Приколно =)
          Я кстати видел длинную регулярку с поддержкой все ютуб линков, но ввиду ее сложности подумал что пихать ее в туториал будет излишним
          • +2
            Может быть проще и надежнее использовать oembed?
            • 0
              А тамбнейла там нет в респонсе =\
              • 0
                Разве?
                youtube
                vimeo
                Более того, там есть даже размеры превьюшки:
                <thumbnail_url>http://b.vimeocdn.com/ts/294/128/29412830_1280.jpg</thumbnail_url>
                <thumbnail_width>1280</thumbnail_width>
                <thumbnail_height>720</thumbnail_height>
                
          • 0
            Спасибо =)
            • +1
              Интересно, что их сайт PHPixie сделан на Wordpress
              • 0
                Ну форум коханы тоже не на кохане и тд.
                Вордпрес идеален имхо для писания постов и коментов.
                А писать фактически новый ЦМС и форум и тд работа не одного дня.
                ЦМСок на пиксе еще не видел кстати
              • 0
                Спасибо за обзор, но мне кажется, что не хватает сравнения с конкурентами по фичам и ощущениям.
              • 0
                Вот любят же люди себе в ногу стрелять. Назвал бы dracony свой фреймворк как-то иначе — с учетом зомби-состояния развития Коханы и популярность бы была и народ о нем рассказывал.

                А сейчас заходишь на сайт, видишь феечку, и перед внутренним взором встает образ школьника, который решил написать очередной «свой» фреймворк. Детский сад «Солнышко». Упор на быстроту исполнения эту гипотезу только подтверждает — обычно только неофиты озабочены быстротой исполнения php — одинарные/двойные кавычки, for/foreach, вот это все, я думаю, все насмотрелись в свое время на таких персонажей. Думаешь «WTF ?» и закрываешь таб. Доверять судьбу своего проекта вот этому? Нет, спасибо.

                Получается, то автор своими руками почти хоронит свое детище. А жаль, фреймворк-то вполне ничего себе.
                • 0
                  правда =(
                  Я бы намного меньше затруднялся с выбором если бы имя было другим.
                  Ну с другой стороны помогает отсеять ентерпрайзщиков =)
                  • +2
                    Ну не знаю. Лично меня огорчает лишь то что фреймворк называется не PHPony.

                    • 0
                      PHPony — это было бы как раз очень круто, масса внимания со всего интернета и слоган «на 20% лучше любых других фреймворков».

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.