PHP:将类方法限制为相关类

问题描述 投票:0回答:1

很抱歉,如果之前有人问过这个问题,但谷歌搜索没有给我。

如何保护方法(或属性)仅免受不相关类的影响,但又可用于特定的相关类?

class supplier {
    protected person $contactPerson;
}

class unrelated {
    function unrelatedStuff(supplier $supplier) {
        $noneOfMyBusiness = $supplier->contactPerson; // should generate error
    }
}

class order {

    function __construct(readonly public supplier $supplier) {}

    function informAboutDelivery() {
         $contact = $this->supplier->contactPerson; 
         // should work (but doesn't) since to process an order you need the suppliers details
         $contact->mail('It has been delivered');
    }
}

我编写了一个特征,可以使用 __method 魔术方法和属性来允许访问某些预定义类的某些方法,同时禁止所有其他访问。我还可以想到使用反射。但我觉得这一切都过于复杂,而且我在这里遗漏了一些非常明显的东西。许多类密切相关,而另一些则无关。处理这个问题的正常方法是什么?如何屏蔽信息但不是所有类别的信息?

php class restriction
1个回答
0
投票

使用带有回溯的魔术方法怎么样?


class supplier {

    private $_contact;

    //DEFINE THE CLASSES THAT ARE ALLOWED TO ACCESS PROPERTIES
    private $_allowedClasses = [
        'contact' => [
            order::class,
            //Another::class
        ],
        'otherProperty' => [
            //Another::class
        ]
    ];

    public function __get($name){
        
        //DEFINE THE PREFIXED NAME
        $prefixed = '_'.$name;

        //CHECK IF THE ATTRIBUTE EXISTS
        if(isset($this->$prefixed){

            //GET THE BACKTRACE EFFICIENTLY
            $trace = debug_backtrace(2);

            //CHECK IF THE CALLING CLASS IS ALLOWED
            if(isset($this->_allowedClasses[$name] && isset($trace[1]['class']) && !in_array($trace[1]['class'])){
                throw new \Exception("{$trace[1]['class]} is not allowed to access this");
            }

            //SEND BACK THE VALUE
            return $this->$prefixed;
        }
    }
}

class unrelated {
    public function unrelatedStuff(supplier $supplier){
        return $supplier->contact; //THROWS AN ERROR BECAUSE THIS CLASS CANT CALL THE contact PROPERTY
    }
}

class order {

    protected $supplier;

    public function __construct(supplier $supplier){

        //SET SUPPLIER
        $this->supplier = $supplier;
    }

    //GET THE CONTACT (IF THIS CLASS IS NOT ALLOWED AN ERROR WILL BE THROWN)
    $contact = $this->supplier->contact;

    //SEND YOUR EMAIL
    $contact->mail("Some message");
}
© www.soinside.com 2019 - 2024. All rights reserved.