方法中的 php 类方法

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

如果我想访问公共方法,我可以轻松做到。但是如果我想访问方法内的属性,我应该做什么,是否推荐?

我可以在 php 中做这样的事情吗?

class Auth {
   public function check($user = false){
    $project = false; //make it somehow public
     if($user == 'user1'){
       $this->project = 1;
     }
   }
}

比其他地方

$auth = new Auth();
$auth->check('user1')->project;

只是为了让大家知道这是可能的,这是来自

Zend framework

代码

Zend-Authentication

 if ($result->isValid()) {
            $this->getStorage()->write($result->getIdentity());
        }
php zend-framework php-7 object-oriented-analysis
6个回答
3
投票

我相信你的问题基本上是关于流畅的接口或方法链接与魔术方法

__get

尝试运行此:

<?php
class Auth {
   public function check($user = false){
    $project = false; //make it somehow public
     if($user == 'user1'){
       $this->project = 1;
     }
   }
}

$auth = new Auth();
$auth->check('user1')->project;

结果:

注意:第 13 行尝试获取 /in/Hi5Rc 中非对象的属性

因为

$auth->check('user1')
返回 NULL(或 void),并且 NULL 没有
project
属性。

我们需要的第一件事是让

$auth->check('user1')
返回一些有用的东西。鉴于
$project
是布尔值,而
$this->project
是整数,因此最有意义的是返回
$project
并获取值。

<?php
class Auth {
   public function check($user = false){
    $project = false; //make it somehow public
     if($user == 'user1'){
       $this->project = 1;
     }
    return $project;
   }
}

$auth = new Auth();
print_r($auth->check('user1'));

结果是:

布尔(假)

但这并不能解决您关于如何流畅访问非公共字段或参数的问题。

您似乎误以为这些项目正在使用$project类中的

方法作用域变量
(如
check()
)并使它们可访问。他们不是。

甚至在您的 Zend-Authentication 示例中也没有。

字段

$storage
本身是受保护的,但它具有公共(流畅)getters/setters

因此,

$this->getStorage()
返回
new Storage\Session()
的实例,它具有公共
write()

因此

$this->getStorage()->write()
有效。

因此,让我们对示例类进行一些修改以进行演示。

<?php
class Project{
    /**
     * @var string
     */
    private $name;
    /**
     * @var bool
     */
    private $active;
    /**
     * @var string
     */
    private $description;

    public function __construct($name = 'Default', $active = false, $description = '')
    {
        $this->name = $name;
        $this->active = $active;
        $this->description = $description;
    }

    /**
     * @param string $name
     *
     * @return Project
     */
    public function setName(string $name): Project
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @param bool $active
     *
     * @return Project
     */
    public function setActive(bool $active): Project
    {
        $this->active = $active;

        return $this;
    }

    /**
     * @param string $description
     *
     * @return Project
     */
    public function setDescription(string $description): Project
    {
        $this->description = $description;

        return $this;
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->active;
    }

    /**
     * @return string
     */
    public function getDescription(): string
    {
        return $this->description;
    }

    public function toArray(){
        return [
            'name' => $this->name,
            'active' => $this->active,
            'description' => $this->description
        ];
    }

    public function toJson(){
        return json_encode($this->toArray());
    }

    public function __toString()
    {
        return $this->toJson();
    }
}



class Auth {

    /**
     * @var Project
     */
    private $project;

    public function __construct($project = Null)
    {
        $this->project = is_null($project)? new Project() : $project;
    }

    public function check($user = false){
        if($user == 'user1'){
            $this->project->setName("Project: $user")->setActive(true)->setDescription("This project belongs to $user");
        }
        return $this;
    }

    /**
     * @param Project $project
     *
     * @return Auth
     */
    public function setProject(Project $project): Auth
    {
        $this->project = $project;

        return $this;
    }

    /**
     * @return Project
     */
    public function getProject(): Project
    {
        return $this->project;
    }

}

$auth = new Auth();
echo $auth->check('user1')->getProject();

现在的结果是:

{"name":"项目:user1","active":true,"description":"该项目 属于用户1”}

但是,您希望像访问公共字段一样访问 private 字段,而不使用定义的 getter/setter。因此,让我们对

Auth
类进行更多更改。

class Auth {

    /**
     * @var Project[]
     */
    private $private_project;

    public function __construct($project = Null)
    {
        $this->private_project = is_null($project)? new Project() : $project;
    }

    public function check($user = false){
        if($user == 'user1'){
            $this->private_project->setName("Project: $user")->setActive(true)->setDescription("This project belongs to $user");
        }
        return $this;
    }

    public function __get($name)
    {
        if ($name === 'project'){
            return $this->private_project;
        }
    }

}

现在您可以按照您的要求流畅地访问该字段了:

$auth = new Auth();
echo $auth->check('baduser')->project;
echo  "\n";
echo $auth->check('user1')->project;

结果:

{"名称":"默认","活动":false,"描述":""}

{"name":"项目:user1","active":true,"description":"该项目属于user1"}

Laravel 的 Eloquent 模型充分利用

__get()
函数来动态访问模型字段。 Laravel 还充分利用了
__call()
魔法方法来提高流畅度。

我希望这有助于澄清一些问题。


3
投票
class Auth
{
   protected $project;

   public function __constructor($project = false)
   {
        $this->project = $project;
   }

   public function check($user = false)
   {
     if($user == 'user1')
     {
       $this->project = 1;
     }

      return $this;
   }

   public function project()
   {
       return $this->project;
   }
}

然后您可以执行以下操作:

$auth = new Auth();
$auth->check('user1')->project(); // returns 1

或者如果您愿意,您还可以在构造函数中为

$project
设置另一个默认值

$auth = new Auth($other_default_value);
$auth->check('user2')->project();  // returns $other_default_value

1
投票

如果您不想创建额外的类属性和“保留方法链”,那么

yield
呢?

class Auth
{
   public function check($user = false)
   {
       $project = false; // make it somehow public

       if($user === 'user1'){
           (yield 'project' => $project); // making it public
       }

       return $this;
   }
}

稍后你可以发现它如下:

$array = iterator_to_array($auth->check($user));
// array(1) { ["project"] => bool(false) }

但是要使用此功能,您将无法使用方法链接,因为无论如何您都需要检索生成器,因此最好修改方法来发现

$project


0
投票
<?php
class Auth
{
    public $project;
    public function check($user = false)
    {
        $this->project = false;//make it somehow public
        if ($user == 'user1') {
            $this->project = 1;
        }
        return $this;
    }
}

$auth = new Auth();
var_dump($auth->check('user1')->project);

这将返回 1。函数中定义的局部变量只能在函数内部访问,不能在外部访问,因此您需要全局定义它们


0
投票

$project
是您的情况下的局部变量,在
check
方法的范围内可见。您可以将其定义为成员:

class Auth {
   public $project = false;
   public function check($user = false){
     if($user == 'user1'){
       $this-project = 1;
     }
   }
}

但是,建议创建成员

public
并通过getter访问它,这将检查它是否已初始化,如果没有,则初始化它:

class Auth {
   private $project = false;
   public getProject($user = false) {
      if ($this->project === false) {
          check($user);
      }
      return $this->project;
   }
   public function check($user = false){
     if($user == 'user1'){
       $this-project = 1;
     }
   }
}

0
投票

您需要将其添加为类变量:

class Auth {
   public $project = false;

   public function check($user = false) {
     if($user == 'user1'){
       $this->project = 1;
     }
   }
}

该房产的可用方式如下:

$auth = new Auth ();
$auth->check ('user1');
echo $auth->project; // 1
© www.soinside.com 2019 - 2024. All rights reserved.