Так перестали бы?
Может есть смысл тогда сделать опрос? Я конечно понимаю что те кто ставит вордпрес могут купит такой хостинг, но нормальный программер, если он уже и фреймворк выучил купит ли такой?
Нет ну я не спорю что есть кейсы когда ИН может быть оправдан, но думаю много проектов как вы сами сказали бывают на шерд хостингах где таких няшек нет.
К слову вот я сделал бенчмарк и протестировал поиск по LIKE и по полю с индексом, результат (время исполнения 10000 запросов в секундах):
LIKE test
IN: 35
JOIN: 36
Test Indexed field
IN: 34
JOIN: 29
JOIN работает быстрее на полях с ключами, так как не надо тратить время на собирания массива с айдишками. Кроме того он более читабелен и такие запросы легче мониторить. Я конечно понимаю что Сфинкс и тд не смогут работать с джойном, но я не понимаю почему ради них должны страдать те кто их не используют. Лучше бы вынести их в отдельную библиотеку.
Кроме того джойн будет использовать курсор а не жрать память попусту.
Код бенчмарка:
<?php
$db = new PDO('mysql:host=localhost;dbname=benchmark', 'root');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
function benchmark($callback){
$t = time();
for ($i = 0; $i < 10000; $i++)
$callback();
return time() - $t;
}
function test_in($db, $query) {
return function() use($db, $query) {
$ids = [];
$posts = [];
foreach($db->query("SELECT * from posts where $query ") as $post) {
$posts[] = $post;
$ids[] = $post['author_id'];
}
$authors = $db->query("SELECT * from authors where id in (".implode(',', $ids).")")->fetchAll();
if (count($authors) != 168)
die;
};
}
function test_join($db, $query) {
return function() use($db, $query) {
$posts = $db->query("SELECT * from posts where $query ")->fetchAll();
$authors = $db->query("SELECT a.id, a.name from authors a
JOIN posts p ON p.author_id = a.id
where p.$query")->fetchAll();
};
}
$in_time = benchmark(test_in($db, "title like '%puzzle%'"));
$join_time = benchmark(test_join($db, "title like '%puzzle%'"));
echo(" LIKE test
IN: $in_time
JOIN: $join_time
");
$in_time = benchmark(test_in($db, "published=1"));
$join_time = benchmark(test_join($db, "published=1"));
echo(" Test Indexed field
IN: $in_time
JOIN: $join_time
");
Стоит учитывать, что на фреймворке будут делаться не только проекты, но и продукты, для которых совместимость с shared-хостингами важна.
То есть как коммунизм, пусть всем будет одинаково плохо. Тогда сразу давайте и замыканий в пхп не использовать, так как на хостингах еще и 5.2 может ПХП стоять.
Кстати а почему не сделать тогда на джойне типа так:
Взяли авторов
Select id,name from authors where name like '%jig%'
Взяли посты
Select posts.id, posts.title from posts INNER JOIN authors on posts.author_id = authors.id where authors.name like '%jig%'
Зачем ходить по массиву авторов, собирать айдишки, потом делать из них список, который потом мускулу передавать длиннейшим стрингом (плохо для дебага потом), который ему потом еще и парсить.
А что делать если у поля праймари ки состоит из двух полей? ИН тогда не сработает
Мммм а почему отрывать руки?
Просто не надо грузить все 1000 записей сразу в память а читать курсором и проблем не будет. А если я например хочу написать скрипт экспорта что мне делать? Для самой базы данных вернуть 1000 строк совсем не проблема
Имхо для работы с Редис надо использовать другой класс совсем а не сваливать все в одну кучу, где ничего не оптимизировано во имя глобализации
Класс ОРМ это «плагин» к контейнеру, то есть он сам по себе является контейнером и просто добавляет фактори методы. то, явно или нет передавать параметры в конструктор зависит уже от самой функции которую вы напишете для своего класса.
Насчет того откуда взялось $pixie->db. Искать придется только в СВОИХ исходниках, то есть в классе App\Pixie где разработчик сам подключает модули и добавляет атрибуты. вам не надо будет лезть в код самого фреймворка.
Конечно если не нравится использовать массив $modules всегда можно подключить модуль явно в конструкторе.
namespace App;
class Pixie extends \PHPixie\Pixie {
public $db;
public function after_bootstrap() {
$this->db = new \PHPixie\DB($this);
}
}
Как я писал, все что в App неймспейсе это только пример, можно писать как больше нравится)
И где тут гарантия? $pimple['db'] тоже может вернуть вам stdClass, если конечно вы скажете ему вернуть его. Так же и $pixie, например $pixie->orm->result() построит вам объект со всеми зависимостями.
Может я плохо объяснил но объекты модулей строятся во время bootstrap(), то есть если вы прописали там модуль то он точно там будет и точно не будет каким-то stdClass
Я не понимаю чем хуже писать так:
public function build_demo(){
return new Demo($this->dependency1(), $this->dependency2())
}
protected $demo;
public function demo() {
if($this->demo == null)
$this->demo = $this->build_demo();
return $this->demo;
}
public function a($param) {
return new A($this->dependency1(), $this->dependency2(), $param);
}
чем так например:
$pimple['demo'] =$c->share(function ($c) {
return new Demo($c['dependency1'], $c['dependency2']);
});
$pimple['a'] = function($param) {
return new A($c['dependency1'], $c['dependency2'],$param);
}
Экономит несколько строк конечно, но приимущиства на лицо:
1) в варианте с пикси IDE будет показывать подсказки по результатам функций. А вот что такое $c['demo'] IDE точно знать не будет
2) все описано как атрибуты класса не возня с магическим массивом
3) код с Пимл фактически недокументируем, так как в phpDocumentor насколько я помню нет возможности описать ключи массива.
Для простоты в \App\Pixie есть $instance_classes которые создаются только раз при первом запросе и которым в конструктор передается $pixie.
По сути да, это то что вы написали, только теперь вам надо еще создать маcсив таких $class чтобы держать их в одном месте и у вас получится свой контейнер =)
Ммм это он о старой версии, в новой нет статиков и она полностью покрыта тестами. С ним есть еще несколько холиваров на реддите, при чем некоторые из его идей таки были имплементированы.
Имхо сам Фил немного слишком вспыльчив, как минимум раз в неделю он кого-то бранит на своем блоге, то разработчиков самого ПХП, то программистов с кривыми руками итд
Да, в этом идея (и одна из проблем) DI контейнеров. Правда стоить отметить что $pixie->db сам по себе никуда не пропадет, то есть если вы написали код и он там был то он там и будет =)
А то что это может быть stdClass это фича а не баг, если его можно подменить на что-нибудь то протестировать ОРМ будет гораздо проще так как вместо DB я просто вставлю его мок
Главное отличие в том что его можно подменить в одном месте, в то время как вызов статика включает имя класса и поэтому подменять класс надо в каждом файле где его упоминают
И да и нет. Если например применить ее к скажем Симфони то схема будет очень поверхностная, так как в симфони кроме этого на каждой стадии еще много всего делается. Для пикси же ( в Core которой только горстка классов) кроме того что на схемке мало что происходит.
Может есть смысл тогда сделать опрос? Я конечно понимаю что те кто ставит вордпрес могут купит такой хостинг, но нормальный программер, если он уже и фреймворк выучил купит ли такой?
PHPixie использует только 1 запрос чтоб сразу взять и пост и автора. даже с оверхедом фреймворка получатся так:
LIKE test 22
Test Indexed field 20
Фактически 40% экономии
К слову вот я сделал бенчмарк и протестировал поиск по LIKE и по полю с индексом, результат (время исполнения 10000 запросов в секундах):
LIKE test
IN: 35
JOIN: 36
Test Indexed field
IN: 34
JOIN: 29
JOIN работает быстрее на полях с ключами, так как не надо тратить время на собирания массива с айдишками. Кроме того он более читабелен и такие запросы легче мониторить. Я конечно понимаю что Сфинкс и тд не смогут работать с джойном, но я не понимаю почему ради них должны страдать те кто их не используют. Лучше бы вынести их в отдельную библиотеку.
Кроме того джойн будет использовать курсор а не жрать память попусту.
Код бенчмарка:
<?php $db = new PDO('mysql:host=localhost;dbname=benchmark', 'root'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); function benchmark($callback){ $t = time(); for ($i = 0; $i < 10000; $i++) $callback(); return time() - $t; } function test_in($db, $query) { return function() use($db, $query) { $ids = []; $posts = []; foreach($db->query("SELECT * from posts where $query ") as $post) { $posts[] = $post; $ids[] = $post['author_id']; } $authors = $db->query("SELECT * from authors where id in (".implode(',', $ids).")")->fetchAll(); if (count($authors) != 168) die; }; } function test_join($db, $query) { return function() use($db, $query) { $posts = $db->query("SELECT * from posts where $query ")->fetchAll(); $authors = $db->query("SELECT a.id, a.name from authors a JOIN posts p ON p.author_id = a.id where p.$query")->fetchAll(); }; } $in_time = benchmark(test_in($db, "title like '%puzzle%'")); $join_time = benchmark(test_join($db, "title like '%puzzle%'")); echo(" LIKE test IN: $in_time JOIN: $join_time "); $in_time = benchmark(test_in($db, "published=1")); $join_time = benchmark(test_join($db, "published=1")); echo(" Test Indexed field IN: $in_time JOIN: $join_time ");
То есть как коммунизм, пусть всем будет одинаково плохо. Тогда сразу давайте и замыканий в пхп не использовать, так как на хостингах еще и 5.2 может ПХП стоять.
Взяли авторов
Select id,name from authors where name like '%jig%'
Взяли посты
Select posts.id, posts.title from posts INNER JOIN authors on posts.author_id = authors.id where authors.name like '%jig%'
Зачем ходить по массиву авторов, собирать айдишки, потом делать из них список, который потом мускулу передавать длиннейшим стрингом (плохо для дебага потом), который ему потом еще и парсить.
А что делать если у поля праймари ки состоит из двух полей? ИН тогда не сработает
Просто не надо грузить все 1000 записей сразу в память а читать курсором и проблем не будет. А если я например хочу написать скрипт экспорта что мне делать? Для самой базы данных вернуть 1000 строк совсем не проблема
Имхо для работы с Редис надо использовать другой класс совсем а не сваливать все в одну кучу, где ничего не оптимизировано во имя глобализации
Насчет того откуда взялось $pixie->db. Искать придется только в СВОИХ исходниках, то есть в классе App\Pixie где разработчик сам подключает модули и добавляет атрибуты. вам не надо будет лезть в код самого фреймворка.
Конечно если не нравится использовать массив $modules всегда можно подключить модуль явно в конструкторе.
Как я писал, все что в App неймспейсе это только пример, можно писать как больше нравится)
Я где-то сказал что-то об оценке? Просто мне понравилась фраза Кохана Lite
Может я плохо объяснил но объекты модулей строятся во время bootstrap(), то есть если вы прописали там модуль то он точно там будет и точно не будет каким-то stdClass
Я не понимаю чем хуже писать так:
чем так например:
Экономит несколько строк конечно, но приимущиства на лицо:
1) в варианте с пикси IDE будет показывать подсказки по результатам функций. А вот что такое $c['demo'] IDE точно знать не будет
2) все описано как атрибуты класса не возня с магическим массивом
3) код с Пимл фактически недокументируем, так как в phpDocumentor насколько я помню нет возможности описать ключи массива.
Для простоты в \App\Pixie есть $instance_classes которые создаются только раз при первом запросе и которым в конструктор передается $pixie.
twitter.com/philsturgeon/status/327179286366793729
Пример класса модуля: github.com/dracony/PHPixie-ORM/blob/master/classes/PHPixie/ORM.php
По сути да, это то что вы написали, только теперь вам надо еще создать маcсив таких $class чтобы держать их в одном месте и у вас получится свой контейнер =)
Имхо сам Фил немного слишком вспыльчив, как минимум раз в неделю он кого-то бранит на своем блоге, то разработчиков самого ПХП, то программистов с кривыми руками итд
А то что это может быть stdClass это фича а не баг, если его можно подменить на что-нибудь то протестировать ОРМ будет гораздо проще так как вместо DB я просто вставлю его мок