在我正在创建的应用程序中,我需要将未知数量的参数传递给类的未知构造函数。 类(+ namespace)是一个字符串,在$ class中。 参数在一个数组中。
这个应用程序将在几个月内部署,所以我们认为我们可以在PHP 5.6中开发它。 所以我认为解决方法是:
$instance = new $class(...$args);
这是有效的......
但是我的同事不想接受这个,因为CI服务器不理解这行代码。 他们的解决方案宁愿是:
$reflect = new \ReflectionClass($class);
$instance = $reflect->newInstanceArgs($args)
现在:两者都工作正常,所以这不是问题。 但我的想法是,反射比其他方式慢(如PHP 5.6 splat运算符)。
还有一个问题:反思是一种好方法,我应该从CI服务器理解该行的那一刻起使用splat运算符吗?
答案 0 :(得分:7)
绝对选择splat运算符,为什么?它比反射方法快得多(我使用它并且实现似乎非常好)。反射也会破坏与设计有关的任何事情,例如,它允许你打破封装。
PS:不是$instance = new $class(...$args);
吗?
答案 1 :(得分:7)
今天我找到了时间进行基准测试 这就像我预期的那样(和Fleshgrinder说):splat运算符更快。
基准时间:
反思:11.686084032059s
Splat:6.8125338554382s
几乎有一半的时间......这很严重......
基准(通过http://codepad.org/jqOQkaZR):
<?php
require "autoload.php";
function convertStdToCollectionReflection(array $stds, $entity, $initVars)
{
$records = array();
$class = $entity . '\\Entity';
foreach ($stds as $record) {
$args = array();
foreach ($initVars as $var) {
$args[] = $record->$var;
}
$reflect = new \ReflectionClass($class);
$records[] = $reflect->newInstanceArgs($args);
}
return $records;
}
function convertStdToCollectionSplat(array $stds, $entity, $initVars)
{
$records = array();
$class = $entity . '\\Entity';
foreach ($stds as $record) {
$args = array();
foreach ($initVars as $var) {
$args[] = $record->$var;
}
$records[] = new $class(...$args);
}
return $records;
}
$dummyObject = array();
for ($i = 0; $i < 10; $i++) {
$dummyclass = new \stdClass();
$dummyclass->id = $i;
$dummyclass->description = 'Just a number... ' . $i;
$dummyObject[] = $dummyclass;
}
print 'Start Reflection test' . PHP_EOL;
$reflectionStart = microtime(true);
for($i = 0; $i < 1000000; $i++) {
convertStdToCollectionReflection(
$dummyObject,
'Xcs\Core\Record',
array(
'id',
'description'
)
);
}
$reflectionEnd = microtime(true);
print 'Start Splat test' . PHP_EOL;
$splatStart = microtime(true);
for($i = 0; $i < 1000000; $i++) {
convertStdToCollectionSplat(
$dummyObject,
'Xcs\Core\Record',
array(
'id',
'description'
)
);
}
$splatEnd = microtime(true);
print PHP_EOL . 'OUTPUT:' . PHP_EOL;
print 'Reflection: ' . ($reflectionEnd - $reflectionStart) . 's' . PHP_EOL;
print 'Splat: ' . ($splatEnd - $splatStart) . 's' . PHP_EOL;