PHP相当于朋友或内部

时间:2008-11-25 16:00:40

标签: php oop friend

在php中是否有一些“朋友”或“内部”?如果没有,是否有任何模式可以实现这种行为?

修改 对不起,但标准的Php不是我想要的。我正在寻找一些类似于指挥官所做的事情。

我的课程在后端进行C风格的系统调用,并且杂耍开始变得麻烦。我在对象A中有函数,它将对象B作为参数接受,并且必须调用对象B中的方法作为参数传递。最终用户可以在B中调用该方法,系统将崩溃。

4 个答案:

答案 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,以确保发生握手。

请点击此处:https://gist.github.com/mcamiano/00592fb400e5043d8acd

答案 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);