在使用方法链接的PHP中,如何在链中调用最后一个方法之后提供函数调用?
同时使用相同的实例(见下文)。这会破坏实现析构函数的想法。
最终结果是私有" insert()"的返回值和函数调用。来自定义的链属性(当然),无需订购,无需公开调用。
注意,如果我一起回显(__toString)方法,它将检索最终生成的唯一代码,这是投射字符串的正常行为。
以下示例:
class object
{
private $data;
function __construct($name) {
// ... some other code stuff
}
private function fc($num) {
// some wicked code here
}
public function green($num) {
$this->data .= fc($num*10);
return $this;
}
public function red($num) {
$this->data .= fc($num*25);
return $this;
}
public function blue($num) {
$this->data .= fc($num*1);
return $this;
}
// how to get this baby to fire ?
private function insert() {
// inserting
file_put_content('test_code.txt', $this->data);
}
}
$tss = new object('index_elements');
$tss->blue(100)->green(200)->red(100); // chain 1
$tss->green(0)->red(100)->blue(0); // chain 2
$tss->blue(10)->red(80)->blue(10)->green(0); // chain 3
链 1 , 2 , 3 会根据方法中的所有值生成唯一代码并提供操作,例如自动插入DB或创建文件(在本例中使用)。
正如您所看到的,没有发生任何字符串设置或转换或回显。
答案 0 :(得分:3)
您可以保留需要初始化的事项列表以及是否 在这种情况下是这样的。然后在每次使用时检查列表 一种初始化方法。类似的东西:
class O {
private $init = array
( 'red' => false
, 'green' => false
, 'blue' => false
);
private function isInit() {
$fin = true;
foreach($this->init as $in) {
$fin = $fin && $in;
}
return $fin;
}
public function green($n) {
$this->init['green'] = true;
if($this->isInit()) {
$this->insert();
}
}
public function red($n) {
$this->init['red'] = true;
if($this->isInit()) {
$this->insert();
}
}
public function blue($n) {
$this->init['blue'] = true;
if($this->isInit()) {
$this->insert();
}
}
private function insert() {
echo "whee\n";
}
}
但我个人认为这样做会更麻烦。更好的imo
公开你的insert
方法,并让你的代码的用户知道什么时候
初始化完成。所以应该使用的东西如下:
$o->red(1)->green(2)->blue(0)->insert();
-update -
如果情况不可能预测需要调用哪些功能 你真的需要明确它。我无法看到解决方法。原因 是的,PHP真的无法区分
$o1 = new A();
$o2 = $o1->stuff();
和
$o2 = (new A())->stuff();
在一种允许重载=
的语言中,我想这可能是真的
真的很混乱,一般不是个好主意。
可以移动显式部分,使其不在通话结束时 链,但我不确定这是否会让你更快乐?它也会反对 你不想使用其他实例的愿望。它可能看起来像这样:
class O {
public function __construct(InitO $ini) {
// Do stuff
echo "Whee\n";
}
}
class InitO {
public function red($n) {
return $this;
}
public function green($n) {
return $this;
}
public function blue($n) {
return $this;
}
}
$o = new O((new InitO())->red(10)->red(9)->green(7));
当然,您可以通过使用其他一些包装方式来使用一个实例 但我现在能想到的唯一方法看起来会更加丑陋。
答案 1 :(得分:1)
我和PeeHaa,这没有任何意义! :)
在使用最后一个链(无法展望未来)之后,只有神奇地发生某些事情的机会是Destructor / Shutdown函数或者手动转换/调用insert()
答案 2 :(得分:0)
您还可以决定在不使用对象的情况下静态实现此目的。
belongsToMany
答案 3 :(得分:0)
好,让我们看一个代码示例
<?php
// map dummy class
class map
{
// __call magic method
public function __call($name, $args)
{
return $this;
}
}
// now we chain
$map = new map;
// let's find me
$map->start('here')
->go('right')
->then()
->turn('left')
->and('get water')
->dontEat()
->keep('going')
->youShouldSeeMe('smiling');
在这里我们不知道最后一个方法是什么,一旦到达终点,就需要触发某种操作或事件。
根据数据结构,我们可以将其称为LIFO堆栈。 (后进先出)
那我如何在PHP上解决这个问题呢?
//我做了一些追溯
...返回__call函数
function __call($name, $args)
{
$trace = debug_backtrace()[0];
$line = $trace['line'];
$file = $trace['file'];
$trace = null;
$getFile = file($file);
$file = null;
$getLine = trim($getFile[$line-1]);
$line = null;
$getFile = null;
$split = preg_split("/(->)($name)/", $getLine);
$getLine = null;
if (!preg_match('/[)](->)(\S)/', $split[1]) && preg_match('/[;]$/', $split[1]))
{
// last method called.
var_dump($name); // outputs: youShouldSeeMe
}
$split = null;
return $this;
}
当我们触底时,whoolla我们可以叫任何东西。 *(请注意,一旦我完成了变量操作,我就会使用null,我来自我们自己管理内存的C系列)
希望这对您有帮助。