【问题标题】:property visibility, getters and setters PHP属性可见性、getter 和 setter PHP
【发布时间】:2014-06-19 10:52:09
【问题描述】:

我正在开发一种关于帖子、cmets 和点赞的 PHP 插件。所以我会有 Post、Comment 和 Like 的对象。

这个类有一堆属性来描述它自己的类,Post 类的一个小例子就可以了。

class Post
{
    protected $infoPost;

    protected $postId;

    protected $content;

    protected $poster_type;

    protected $poster_id;

    protected $likes;

    protected $comments;

    // and more but you got the idea

    public function __construct($postId,
                                $poster_type = null,
                                $poster_id = null,
                                $content = null,
                                $likes = null,
                                $comments = null)

           $this->postId = $postId;
           $this->poster_type = $poster_type;
           $this->poster_id = $poster_id;
           $this->content = $content;
           $this->likes = $likes;
           $this->comments = $comments;

}

现在名为Wall 的类将负责实例化和填充对象PostCommentLike 的属性。

仅出于本示例的目的,我将存储库作为依赖项注入,在真正的类上将注入*类,并将存储库作为依赖项。甚至更好地将其提取到界面中。这是一个丑陋的类,但我想保持简单并专注于属性。

class Wall
{

    protected $postRepo;

    protected $commentRepo;

    protected $likeRepo;

    protected $post;

    protected $content;

    protected $likes;

    protected $comments;

    public function __construct(PostRepository $postRepo,
                                CommentRepository $commentRepo,
                                LikeRepository $likeRepo)
    {
           $this->postRepo = $postRepo; 
           $this->commentRepo = $commentRepo;
           $this->likeRepo = $likeRepo;
    }

    // Return Post Object
    public function createPost($postId,$posterType,$posterId)
    {
       $postOrmObject = $this->postRepo->create($postId,$posterType,$posterId);
       $post = new Post($postOrmObject->id,$postOrmObject->posterType,$postOrmObject->posterId);
       $this->post = $post;
       $post->setInfoPost($postOrmObject);
       return $post;
    }

    // Return Content Object
    public function createContent($postId,array $contentInfo)
    {
       $contentOrmObject = $this->contentRepo->create($postId,$content)
       $content = new Content($contentOrmObject->postId,$contentInfo);
       $this->content = $content;

       if ($this->post instanceof Post)
       {
          // here where I change the property
          $this->post->setContent($content);
       }

       return $content;
    }

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

所以在这一点上,我知道这些对象的属性应该是动态的,但同时受到保护,因为只有 1 个类有责任更改它,但对于其他类可能对获取该属性的数据有用。

好的,好吧,此时设置 getter 和 setter,但是有了 10 个属性,我遇到了一个交叉,我的类上多了 20 个方法,我也想避免这种情况。

另一种方法是设置魔术方法__get__set,但设置公共属性的方法似乎相同,而且可能效率更高。

到了这个时候,我提出了几个问题。当我谈论属性时,我指的是PostCommentLike 对象而不是Wall

1) 是否有任何其他解决方案允许Wall 类编辑这些属性但仍保持该属性的受保护可见性并且没有设置器和获取器?使用反射有意义吗?

2) 您认为将这些属性设为公开更好吗?如果是,为什么?

3) 您何时确定何时适合在类中使用属​​性的特定可见性? (只是想将我的想法与您的想法进行比较)

【问题讨论】:

    标签: php properties


    【解决方案1】:

    1) 获得动态保护(或私有)值的方法是使用数组。 protected $data = array(); 然后您可以对受保护的值使用__set__get 方法,因为您不想使用getter 和setter。反射将使您的值易于访问,即使它们是受保护的或私有的。

    2) 我个人主要使用受保护的值,在你的情况下,我也会保护它们。没有其他对象只能更改这些值,它们属于该对象。

    3) 继续 2。对我来说,大多数价值观都受到保护。它们属于特定对象,任何人都不应更改,也不应为此显示。如果不同的对象想要更改或显示值,它应该通过保存数据的当前对象,并且应该告诉调用对象如何以及做什么/显示。

    我个人喜欢这篇文章:https://*.com/a/21902271/660410 它并没有直接回答您的问题,但很好地理解了三个可见性关键字。 (尤其是图片)。

    【讨论】:

    • 非常感谢您的精彩解释,关于您的第三点,我只有一个问题。 您说:“如果不同的对象想要更改或显示值,它应该通过保存数据的当前对象,并且应该告诉调用对象如何以及做什么/显示。” 问题:您如何从给定对象访问该属性?假设我正在注入在将编辑值的类中的构造上保存数据的对象。你能举一个关于你的观点的简短例子吗?将不胜感激谢谢
    • 非常感谢您的回答非常有帮助