在php中是否有一些“朋友”或“内部”?如果没有,是否有任何模式可以实现这种行为?
修改 对不起,但标准的Php不是我想要的。我正在寻找一些类似于指挥官所做的事情。
我的课程在后端进行C风格的系统调用,并且杂耍开始变得麻烦。我在对象A中有函数,它将对象B作为参数接受,并且必须调用对象B中的方法作为参数传递。最终用户可以在B中调用该方法,系统将崩溃。
答案 0 :(得分:44)
PHP不支持任何类似朋友的声明。可以使用PHP5 __get和__set方法模拟这个并仅检查允许的朋友类的回溯,尽管执行此操作的代码有点笨拙。
在PHP的网站上有一些sample code和关于该主题的讨论:
class HasFriends
{
private $__friends = array('MyFriend', 'OtherFriend');
public function __get($key)
{
$trace = debug_backtrace();
if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
return $this->$key;
}
// normal __get() code here
trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
}
public function __set($key, $value)
{
$trace = debug_backtrace();
if(isset($trace[1]['class']) && in_array($trace[1]['class'], $this->__friends)) {
return $this->$key = $value;
}
// normal __set() code here
trigger_error('Cannot access private property ' . __CLASS__ . '::$' . $key, E_USER_ERROR);
}
}
(由nerdclub dot net on bugs.php.net的tsteiner证明的代码)
答案 1 :(得分:8)
还可以使用php> = 5.3.3中的握手和闭包来提升特权,即选择性地泄漏数据。
基本上,交互是这样的:类A有一个公共方法,它接受一个B类对象,并调用B-> grantAccess(或你的接口定义的任何东西),并传递一个闭包。封闭use($that,$anythingelseyouneed)
,其中$ that = $ this,以及确定允许访问哪些属性所需的任何其他内容。闭包有一个参数 - 要返回的属性;如果它是$上的属性并且一切都很酷,则闭包返回属性。否则,它返回'',或抛出异常,或者可能是默认值。
B类> grantAccess接受一个可调用的并存储它,在其他方法中使用它来获取闭包允许泄露的私有属性。将B类的默认构造函数设为私有。使用带有A类参数的静态工厂方法构造B,以确保发生握手。
答案 2 :(得分:0)
也许是吗?只是hack,不是来自c ++的真正朋友关键字,在这种情况下,仅适用于构造函数...
<?php
class FooWithFriend {
private function guardOnlyFriend(): void
{
if (( is_a($this, BarFriendOfFoo::class) ) === false ) {
throw new Exception('Only class BarFriendOfFoo he can create me');
}
}
protected function __construct()
{
$this->guardOnlyFriend();
echo 'Hello friend - ';
}
}
final class BarFriendOfFoo extends FooWithFriend {
public function __construct()
{
parent::__construct();
}
}
final class Bar2FriendOfFoo extends FooWithFriend {
public function __construct()
{
parent::__construct();
}
}
$bar = new BarFriendOfFoo();
$bar = new Bar2FriendOfFoo();
$dummy = new FooWithFriend();
答案 3 :(得分:-15)
根据您的使用情况,我很确定您所寻找的是“受保护”还是“私密”。
如果你在一个类中定义一个函数,而你只想让它自己可用,你就会这样定义:
private function foo($arg1, $arg2) { /*function stuff goes here */ }
如果你要在一个类中定义一个函数,你希望这个函数可以从继承自这个类的类中获得,但是不能公开使用,那么就这样定义:
protected function foo($arg1, $arg2)
我很确定在PHP5中默认情况下,函数是公共的,这意味着您不必使用以下语法,但它是可选的:
public function foo($arg1, $arg2) { /*function stuff goes here */ }
在使用公共函数之前,您仍然需要实例化对象。所以我将彻底告诉您,为了在不实例化对象的情况下在类中使用函数,请务必使用以下语法:
static function foo($arg1, $arg2) { /*function stuff goes here */ }
这将允许您仅通过引用类来使用该函数,如下所示:
MyClass::foo($a1, $a2);
否则,您需要执行以下操作:
$myObject = new MyClass();
$myObject->foo($a1, $a2);