【问题标题】:New to OOP PHP, need critique on first Geo RSS ClassOOP PHP 新手,需要对第一个 Geo RSS 类进行批评
【发布时间】:2010-10-22 18:11:44
【问题描述】:

我对 OOP PHP 完全陌生,目前正在阅读“PHP 对象、模式和实践”。我需要开发一些可以生成 GeoRSS 提要的东西。这就是我所拥有的(它工作得很好,我只想批评一下我可以做些什么不同/更有效/更安全):

class RSS {
 public $channel_title;
 public $channel_description;
 public $channel_link;
 public $channel_copyright;
 public $channel_lang;
 public $item_count;
 public function __construct ($channel_title, $channel_description, $channel_link, $channel_copyright, $channel_lang) {
  $this->channel_title = $channel_title;
  $this->channel_description = $channel_description;
  $this->channel_link = $channel_link;
  $this->channel_copyright = $channel_copyright;
  $this->channel_lang = $channel_lang;
  $this->items = "";
  $this->item_count = 0;
    }
 public function setItem ($item_pubDate, $item_title, $item_link, $item_description, $item_geolat, $item_geolong) {
  $this->items[$this->item_count]['pubDate'] = date("D, j M Y H:i:s T",$item_pubDate);
  $this->items[$this->item_count]['title'] = $item_title;
  $this->items[$this->item_count]['link'] = $item_link;
  $this->items[$this->item_count]['description'] = $item_description;
  $this->items[$this->item_count]['geo:lat'] = $item_geolat;
  $this->items[$this->item_count]['geo:long'] = $item_geolong;
  $this->items[$this->item_count]['georss:point'] = $item_geolat." ".$item_geolong;
  $this->item_count++;
 }
 public function getFeed () {
  foreach ($this->items as $item => $item_element) {
   $items .= "    <item>\n";
   foreach ($item_element as $element => $value) {
    $items .= "      <$element>$value</$element>\n";
   }
   $items .= "    </item>\n";
  }
  $feed = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
    . "<rss version=\"2.0\" xmlns:geo=\"http://www.w3.org/2003/01/geo/wgs84_pos#\" xmlns:georss=\"http://www.georss.org/georss\">\n"
    . "  <channel>\n"
    . "    <title>".$this->channel_title."</title>\n"
    . "    <description>".$this->channel_description."</description>\n"
    . "    <link>".$this->channel_link."</link>\n"
    . "    <copyright>Copyright ".date("Y")." ".$this->channel_copyright.". All rights reserved.</copyright>\n"
    . "    <lang>".$this->channel_lang."</lang>\n"
    . $items
    . "  </channel>\n"
    . "</rss>";
  return $feed;
 }
}

【问题讨论】:

  • +1 即使我有一些批评意见,其中大多数都不是那么重要。唯一违反 OO 原则的是使用 public 作为属性;)但除此之外,其他一切都只是关于更好的编码风格;)
  • 是的,您的代码中需要一些时髦的引擎盖。这听起来像是教授在新大学的正式个人介绍。穿着燕尾服和领带喘不过气来!放松一下,让解析器完成你的工作……尤其是。声明和重新声明一切......

标签: php oop class rss georss


【解决方案1】:
  1. 如果没有令人信服的理由将属性设为publicprivate,则属性应始终为protected
  2. 在使用之前声明或启动所有变量:您在类主体中缺少 protected $items,在 getFeed 中缺少 $items = ''
  3. 正确启动变量:$this-&gt;items = array(); in __construct
  4. 不要管理自己的item_count。更好地依赖 PHP 自己的数组附加功能:

    $this->items[] = array(
        'pubDate'      => date("D, j M Y H:i:s T",$item_pubDate),
        'title'        => $item_title,
        'link'         => $item_link,
        'description'  => $item_description,
        'geo:lat'      => $item_geolat,
        'geo:long'     => $item_geolong,
        'georss:point' => $item_geolat." ".$item_geolong,
    );
    

    好多了,不是吗?

  5. 不要声明比你需要的更多的变量:

    foreach ($this->items as $item) {
        $items .= "    <item>\n";
        foreach ($item as $element => $value) {
             $items .= "      <$element>$value</$element>\n";
        }
        $items .= "    </item>\n";
    }
    

    这里你不需要数组键。所以不要在foreach 循环中获取它;)而是使用$item 作为值,这比$item_element 更好。

【讨论】:

  • 1. Gotcha - 我对使用公共与受保护仍然有点生疏。 2. 好点! 3. 有道理。 4. 我的错。 5. 不知道你能做到这一点 - 谢谢!
【解决方案2】:

这里有几点:

  1. 为什么所有成员都是公开的?您在构造函数中设置它们,然后使用它们来构建提要。因此,让任何人随意更改它们可能不是一个好主意。对于每个实例,它们不应该是最终的/不变的吗?
  2. 您的项目可能应该是一个单独的类。每当你看到你正在创建一个像setItem 中那样的大关联数组时,它表明你有另一个对象在玩。所以创建一个class RSSItem 或类似的东西,将这些东西作为成员。

如果我想到更多,我会编辑我的答案。

【讨论】:

  • 1.好点子!我需要重新阅读书中的那一章。 :) 2. 根据您的建议,我会在 RSS 中添加一个“addItem”方法来接受 RSSItem 对象?对吗?
  • 可以这样做,或者您仍然可以采用相同的参数并在函数内构造 RSSItem 对象。但是您建议的方式可能更好,因此其他代码可以单独与项目交互。
【解决方案3】:

我对这个类的唯一疑虑是在你的setItem 函数中,你应该只使用[] 符号来推送这样的关联数组:

 public function setItem ($item_pubDate, $item_title, $item_link, $item_description, $item_geolat, $item_geolong) {
  $this->items[] = array(
                         'pubDate' => date("D, j M Y H:i:s T",$item_pubDate),
                         'title' => $item_title,
                         'link' => $item_link,
                         'description' => $item_description,
                         'geo:lat' => $item_geolat,
                         'geo:long' => $item_geolong,
                         'georss:point' => $item_geolat.' '.$item_geolong);
 }

这样你就可以放弃你的 $item_count 索引变量。

另外,让您的属性为public通常是一个非常糟糕的主意。

【讨论】:

    【解决方案4】:

    对于初学者来说看起来不错!您在哪里处理作为参数发送的数据?就个人而言,我会使用类方法处理所有内容,对象的目的是包含对象。这意味着与它们相关的所有处理都应该发生在类本身内部。

    另外,像 Tesserex 建议的那样,使用继承和公共、私有成员、使用其他类的类也许是一个好主意。尽管如此,OOP 还是不错的开始。

    【讨论】:

    • 数据在数据库查询的其他地方处理。我可能弄错了,但据我所知,对象的目的是使它们可重用。因此,如果我要将所有数据处理都包含在 RSS 类中 - 这会将其限制为我在其中处理的数据。也许我应该创建一个单独的类来获取和处理数据?希望这是有道理的:)
    • 视情况而定,只要表结构可能不同(实际上并不知道您在该 RSS 中输入了什么),当然,最好有两个对象,而不仅仅是一个。我通常倾向于尝试将与对象相关的所有内容放在一起,即使这意味着创建两个或更多类,但要保持它们相关,因此我不会到处拆分代码。我希望你明白我的意思。
    猜你喜欢
    • 2015-04-24
    • 2014-03-27
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    相关资源
    最近更新 更多