後で使用するために変数参照を保持しようとしています。
これが可能かどうかは定かではありませんが、配列要素を初期化し、変数で参照できることを望んでいます。次に、その配列要素の値を何かに設定して、参照された変数から値にアクセスできるようにします。
たとえば、これは機能します:
class Test{
private $_vars = array();
public function bind($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetch($key, &$var){
$var = $this->_vars[$key];
return $this;
}
}
$test = new Test();
$string_set = 'This is a string';
$test->bind('string', $string_set)
->fetch('string', $string_get);
var_dump($string_get);
// expected: string(16) "This is a string"
// actual: string(16) "This is a string"
ここに問題があります。メソッド呼び出しの順序。関数は格納された匿名関数の戻り値を渡す必要があるため、関数が へcall()
の参照を返すことはできません(そうでない場合は、呼び出しをの代わりに並べ替えます)$this
call()
->call()->fetch()
->fetch()->call()
とにかく、fetch()
メソッドはキーで適切な要素を設定$_vars
しNULL
(既存の値を空にするか、初期化します)、その要素を渡された に参照する必要があり$var
ます。
匿名関数が呼び出されると(バインディングが完了した後fetch()
)、 が呼び出されbind()
、要素が$_vars
何にでもバインドされます(この場合はa$string_set
を含むThis is a string
) 私のロジックが正しい場合、fetch()
バインドされた変数($string_get
この場合は )は配列を参照する必要があります$_vars
を参照している要素には、$string_set
が含まれていますThis is a string
。
そのようには見えませんが。失敗しているコードは次のとおりです (簡潔にするために省略されていますが、重要な部分はすべてそこにあります) 。
class Test{
private $_vars = array();
private $_function;
public static function factory(){
return $test = new self(function() use(&$test){
$string_set = 'This is a string';
$test->bind('string', $string_set);
return true;
});
}
private function __construct($function){
$this->_function = $function;
}
public function bind($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetch($key, &$var){
$this->_vars[$key] = null;
$var = &$this->_vars[$key]; // edited; was not assigning by reference
return $this;
}
public function call(){
return (bool) call_user_func($this->_function);
}
}
$return = Test::factory()
->fetch('string', $string_get)
->call();
var_dump($return, $string_get);
// expected: bool(TRUE), string(16) "This is a string"
// actual: bool(TRUE), NULL
私はここでヒナギクを追いかけていますが、これは可能ですか? いずれにせよ、この問題を一目見ただけでも感謝します。どんな洞察も本当に感謝しています。
編集: fetch()
-の行は$var = $this->_vars[$key];
、参照によって配列要素を割り当てていませんでした。に編集しました$var = &$this->_vars[$key];
が、一見効果はありません。
ボーナス: この問題が解決可能であれば、それは明らかに素晴らしいことです。私は実際には、参照ではなく値bind()
を取ることができることを望んでいます。$var
メソッドのシグネチャは のように変更されますset($key, $value)
。とにかく、事前にもう一度感謝します。
一見好奇心旺盛な(あなたの方向 @Tomalak を見て)詳しく説明するために、より完全なクラスと使用シナリオを提供します。
class Action{
private static $_cache = array();
private static $_basePath;
private $_vars = array();
private $_function;
public static function setBasePath($basePath){
$basePath = rtrim($basePath, '/') . '/';
if(!is_dir($basePath)){
// throw exception, $basePath not found
}
self::$_basePath = $basePath;
}
public static function load($actionPath){
$actionPath = self::$_basePath . $actionPath;
if(array_key_exists($actionPath, self::$_cache)){
return self::$_cache[$actionPath];
}
if(!is_file($actionPath)){
// throw exception, $actionPath not found
}
$action = call_user_func(function() use(&$action, $actionPath){
return require($actionPath);
});
if(!($action instanceof self)){
// throw exception, $action of invalid type
}
self::$_cache[$actionPath] = $action;
return $action;
}
public function __construct($function){
if(!is_callable($function)){
// throw exception, $function not callable
}
$this->_function = $function;
}
public function bindReturn($key, &$var){
$this->_vars[$key] = &$var;
return $this;
}
public function fetchInto($key, &$var){
$this->_vars[$key] = null;
$var = &$this->_vars[$key];
return $this;
}
public function run(){
return (bool) call_user_func_array($this->_function, func_get_args());
}
}
############################################################################
// actions/test.php
return new Action(function($name)
use(&$action){
if($name == 'Alice'){
return false;
}
$data = "Hi, my name is {$name}.";
$action->bindReturn('data', $data);
return true;
});
############################################################################
// index.php (or whatever)
$result = Action::load('actions/test.php') // loaded
->fetchInto('data', $data)
->run('Alice');
// Failed
echo $result
? 'Success - ' . $data
: 'Failed';
$result = Action::load('actions/test.php') // called from cache
->fetchInto('data', $data)
->run('Bob');
// Success - Hi, my name is Bob
echo $result
? 'Success - ' . $data
: 'Failed';