Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
// Теперь мы можем использовать $pixie->singleton в любом месте,
// и всегда получить тот же объект. В качестве дополнительного бонуса
// объект будет создан только тогда когда он будет нужен
namespace App; class Pixie extends \PHPixie\Pixie { protected $modules = array( 'db' => '\PHPixie\DB', 'orm' => '\PHPixie\ORM' ); } // Теперь мы можем использовать $pixie->db и $pixie->orm
$pixie->db существует и это именно DB а не stdClass?$db = new DB($config);
function foo() {
global $db;
}
Да, в этом идея (и одна из проблем) DI контейнеров.
class Config {}
class DB {
public function __construct(Config $config) { ... }
}
class ORM {
public function __construct(DB $db) { ... }
}
$pimple['config'] = $pimple->share(function ($pimple) {
return new Config;
});
$pimple['db'] = $pimple->share(function ($pimple) {
return new DB($pimple['config']);
});
$pimple['orm'] = $pimple->share(function ($pimple) {
return new ORM($pimple['db']);
});
$orm = $pimple['orm'];
$orm->doSomething();
$orm, я полностью уверен, что туда пришли все нужные зависимости и мне не нужно ничего проверять. Все зависимости как на ладони. В Вашем случае гарантий никаких и мне нужно постоянно проверять, «а есть ли вообще такой объект?», «а это точно экземпляр нужного класса?» и т.д. 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);
}
И где тут гарантия? $pimple['db'] тоже может вернуть вам stdClass, если конечно вы скажете ему вернуть его.
class ORM {
public function __construct(DB $db) { ... }
}
return new ORM($pimple['db']);
namespace App;
class Pixie extends \PHPixie\Pixie {
protected $modules = array(
'db' => '\PHPixie\DB', // можно это удалить? оно же не связано с ORM, правда?
'orm' => '\PHPixie\ORM'
);
}
// Теперь мы можем использовать $pixie->db и $pixie->orm
Никаким =) ORM доступается к DB через $pixie->db. А вот $pixie передается каждому из модулей в вконструктор
class ORM {
public function foo() {
return $pixie->db->bar();
}
}
namespace App;
class Pixie extends \PHPixie\Pixie {
public $db;
public function after_bootstrap() {
$this->db = new \PHPixie\DB($this);
}
}
'db' => '\PHPixie\DB'
Главное отличие в том что его можно подменить в одном месте, в то время как вызов статика включает имя класса и поэтому подменять класс надо в каждом файле где его упоминают
$class = 'foo';
$class::bar();
$class = 'baz';
$class::bar();
О нем я услышал совсем недавно, его упомянул в своем твите Phil Sturgeon (разработчик PyroCMS и член PHP-FIG) ...
The PHP community has learned so many valuable lessons about FW dev over the last 2 years, yet PHPixie ignores them all...
...This whole class is littered with untestable code.
This is a bunch of static shit in PHPixie which is totally untestable, because of the statics.
О нем я услышал совсем недавно, его упомянул в своем твите Phil Sturgeon (разработчик PyroCMS и член PHP-FIG)
Стоит учитывать, что на фреймворке будут делаться не только проекты, но и продукты, для которых совместимость с shared-хостингами важна.
<?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
");
microtime.IN выбирается больше данных, чем для JOIN.LIMIT 100 хотя-бы.IN ощутимо быстрее.SELECT * from authors, а в другом SELECT a.id, a.name from authors a.IN быстрее или на уровне двух запросов, один из которых JOIN. В один запрос с JOIN (который eager), естественно, на малых объёмах данных, быстрее. Но стоит взглянуть и на абсолютные циферки для извлечения сотни записей:Like test:
IN: 0.031533 s
JOIN: 0.024357 s
EAGER: 0.006185 s
Indexed test:
IN: 0.005537 s
JOIN: 0.005744 s
EAGER: 0.001047 s
IN и JOIN фактически нет, а отставание от EAGER ничтожно.EXPLAIN. Про более 1000 строк в одном запросе я уже говорил. Так делать не стоит....я взял time() но прогнал каждый подход 10000 раз (
Как работает PHPixie — Жизнь одного запроса, контейнер и парадигма