PHP 相当于 JavaScript 绑定
PHP equivalent of JavaScript bind
首先请原谅我的英语,我不是母语人士,如果它看起来很粗糙,很抱歉,这是我第一次在这个网站上发布。我认为我的问题很简单。假设我们有:
class A {
function foo() {
function bar ($arg){
echo $this->baz, $arg;
}
bar("world !");
}
protected $baz = "Hello ";
}
$qux = new A;
$qux->foo();
在此示例中,"$this"显然不是指我的对象"$qux"。
我应该怎么做才能让它引用"$qux"?
就像在JavaScript中一样: bar.bind(this, "world !")
PHP 没有嵌套函数,所以在你的例子中bar
本质上是全局的。你可以通过使用闭包(=匿名函数)来实现你想要的,它从 PHP 5.4 开始支持绑定:
class A {
function foo() {
$bar = function($arg) {
echo $this->baz, $arg;
};
$bar->bindTo($this);
$bar("world !");
}
protected $baz = "Hello ";
}
$qux = new A;
$qux->foo();
UPD:但是,bindTo($this)
没有多大意义,因为闭包会自动从上下文中继承this
(同样,在 5.4 中)。所以你的例子可以很简单:
function foo() {
$bar = function($arg) {
echo $this->baz, $arg;
};
$bar("world !");
}
UPD2:对于 php 5.3 - 这似乎只有像这样丑陋的黑客才能实现:
class A {
function foo() {
$me = (object) get_object_vars($this);
$bar = function($arg) use($me) {
echo $me->baz, $arg;
};
$bar("world !");
}
protected $baz = "Hello ";
}
在这里,get_object_vars()
用于"发布"受保护/私有属性,使其在关闭中可访问。
实际上,$this
在该上下文中调用时确实指的是$qux
。
您不能在对象方法以外的上下文中使用$this
,因此,如果您采用如下内容:
function test() {
echo $this->baz;
}
无论你做什么,它都行不通。
方式有点奇怪,但是如果你在函数内部使用函数,那么当然一些闭合符是有效的。你可以在 JavaScript 中遇到类似的问题。我建议根本不使用它们,但如果出于某种原因您不想使用它们,那么我会尝试这样(未经测试):
class A {
function foo() {
$that = $this;
function bar ($arg){
echo $that->baz, $arg;
}
bar("world !");
}
protected $baz = "Hello ";
}
$qux = new A;
$qux->foo();
更新如果嵌套函数充当全局函数,那么如果需要使用它,您可以将对象作为参数传递:
函数 foo() {
function bar ($o,$arg){
echo $o->baz, $arg;
}
bar($this,"world !");
}
如果我理解你想要实现的目标,它可能是这样的:
<?php
class Foo {
public $prop;
public function __construct($prop) {
$this->prop = $prop;
}
public function __call($name, $arguments) {
if (!isset($this->$name)) {
throw new InvalidArgumentException("No such property: $name");
}
if (! $this->{$name} instanceof Closure) {
throw new InvalidArgumentException("{$name} is not a closure");
}
$c = $this->{$name}->bindTo($this);
return $c(...$arguments);
}
}
$f = new Foo("bar");
$f->bar = function ($arg) {
print_r([$arg, $this->prop]);
};
$f->bar("A");
?>
这样,您基本上可以对类中的任何函数进行猴子修补,并像本地函数一样调用它,甚至包括使用$this
。但是,有两个限制:
- 这似乎毫无意义,因为特征是可用的,除非您在不可修改的包上添加真正动态定义的
- 尽管闭包可以访问
$this
上的属性,但它仍然是对象的外部,因此只能访问公共属性。尝试访问protected
/private
属性将失败。
- 对象文字方法上的Javascript绑定不起作用
- 视窗 8/Metro UI 数据绑定 JavaScript
- 是否可以绑定javascript函数,使其本地上下文与“this”相同
- 绑定 JavaScript:内联或外部(或脚本)
- 在MVC 4.0中绑定javascript文件
- 如何使用Knockout绑定javascript对话框
- 如何使用angular js在html元素中绑定javascript和ng-click事件
- 如何使用asp.net C#在页面加载时绑定JavaScript事件
- 正在清除WinJS绑定JavaScript数组
- 绑定JavaScript课程未捕获语法错误:意外的令牌<
- 访问嵌套事件绑定javascript中的对象
- 元素在 ajax 显示时不能绑定 Javascript 事件
- 动态绑定javascript与GridView按钮
- 绑定JavaScript's oninput事件的最佳jQuery插件实现
- 实时数据绑定JavaScript
- 为什么我要取消绑定Javascript事件?
- Android绑定JavaScript代码到Android代码不工作
- 如何在ClojureScript中绑定Javascript承诺的解析值
- 绑定javascript滑动和onclick事件到iframe,其中有pdf文档
- 使用knockout.js来跨列绑定javascript关联数组