PHP 5.4.5,这里.我正在尝试调用一个存储为其他对象成员的对象.像这样(非常粗略)
class A {
function __invoke () { ... }
}
class B {
private a = new A();
...
$this->a(); <-- runtime error here
}
Run Code Online (Sandbox Code Playgroud)
当然,这会产生运行时错误,因为没有名为a的方法.但如果我像这样写电话:
($this->a)();
Run Code Online (Sandbox Code Playgroud)
然后我得到一个语法错误.
当然,我可以写
$this->a->__invoke();
Run Code Online (Sandbox Code Playgroud)
但这似乎难以忍受,而且破坏了仿函数的重点.我只是想知道是否有更好的(或官方的)方式.
我知道这个问题已被多次询问,但普遍接受的答案对我没有帮助.但偶然的我偶然发现了答案.
这是设置:我有一大堆查询(主要是CREATE TABLE)通过连接.但是CREATE TRIGGER一直在抛出可怕的2014年错误.这与开放游标无关,因为即使它是程序中唯一的命令也是如此.例如,这失败了:
<?php
$db = new PDO ($cnstring, $user, $pwd);
$db->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute (PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute (PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$st = $db->query ("CREATE TRIGGER `CirclesClosureSync` AFTER INSERT ON Circles
FOR EACH ROW BEGIN
INSERT INTO CirclesClosure (ancestor, descendant)
SELECT ancestor, NEW.ID from CirclesClosure WHERE descendant=NEW.Parent;
INSERT INTO CirclesClosure (ancestor, descendant) values (NEW.ID, NEW.ID);
END;");
$st->closeCursor();
?>
Run Code Online (Sandbox Code Playgroud)
这似乎与涉及创建存储过程的其他问题类似.
这是php 5.4.5,MySql 5.5,Windows XP(虽然它在其他Windows上也失败了)
我想我明白这里发生了什么,但我真的很感激有人说明为什么会发生这种情况.
基本上,(我的编码在飞行这里,给尽可能简单的图示)我有一个S类,除其他事项外,保持与名字的类的对象符号表.所以,我在课堂上定义:
static member (names:Map<string,S> ref) = ref Map.empty
Run Code Online (Sandbox Code Playgroud)
......然后,在S中,我定义:
member this.addSymbol (table: Map<string,S> ref) (name:string)
table := (!table).Add(name, this)
this
Run Code Online (Sandbox Code Playgroud)
我从其他地方称呼这个,因此:
ignore (s.addSymbol S.names "newname")
...
Run Code Online (Sandbox Code Playgroud)
在S.addSymbol里面,我可以看到新的键/值被添加到表中,但是S.names没有得到更新.相反,如果我这样调用addSymbol:
ignore (
let tmp = S.names
s.addSymbol tmp "newName"
)
Run Code Online (Sandbox Code Playgroud)
然后我可以看到tmp正在使用新的键/值对进行更新,但是S.names仍然没有得到更新.
这就是我认为我所知道的:ref机制没有任何问题 - 它在函数内部和外部正确地更新了指示对象.但是静态成员似乎有些奇怪 - 就像,每次都只是递给我相同的静态引用',它复制'a然后为此创建一个新的引用.
我做对了吗?如果是这样,为什么要这样做呢?我能做些什么来让它表现得更明智?
提前致谢.