PHP过程式编程转为面向对象编程(OOP)

3

我正在尝试将我的过程式代码转换为面向对象的代码。

 <?php
 $dbc = get_dbc();
 $info = mysqli_query($dbc, "SELECT info_id, info_title FROM text") or die("Error: ".mysqli_error($dbc));
 while ($info_row = mysqli_fetch_array($info))
 {
      $info_id = $info_row['info_id'];
      $info_title = $info_row['info_title'];
 ?>
 <div style="width: 100%;">
      <div style="float: left;">
           <?php echo $info_id; ?>
      </div>
      <div style="float: left;">
           <?php echo $info_title; ?>
      </div>
      <div style="clear: both;"></div>
 </div>
 <?php } ?>

我的不完整尝试,没有HTML样式的类/对象:

 <?php
 class InfoTest {

      private $info_id;
      private $info_title;

      public function __construct() {
           $dbc = get_dbc();
           $info = $dbc->query ("SELECT info_id, info_title FROM text");
           if ($dbc->error) {
                printf("Error: %s\n", $dbc->error);
           }       
           while ($info_row = $info->fetch_array())
           {
                $info_id = $info_row['info_id'];
                $info_title = $info_row['info_title'];  
           }
           $info->free();
           $this->info_id = $info_id;
           $this->info_title = $info_title; 
      }


      public function setInfoID() {
           $this->info_id = $info_id;
      }

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

      public function setInfoTitle() {
           $this->info_title = $info_title;
      }

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

      public function __destruct() {    
      }

 }

 ?>
 <?php
 $display = new InfoTest();
 echo $display->getInfoID();
 echo $display->getInfoTitle();
 ?>

我的过程式代码输出为:1 One 2 Two。

我的面向对象编程代码输出为:2 Two。

据我理解,面向对象编程以这种方式输出是因为$info_id和$info_title不是数组,并且只打印最后存储的信息。

因此,如果我更改为:

$info_id = $info_row['info_id'];
$info_title = $info_row['info_title'];

To:

$info_id[] = $info_row['info_id'];
$info_title[] = $info_row['info_title'];

我可以打印这些数组,它会显示我想要的所有信息,但如何以非数组形式显示它?

到目前为止,我的做法是否正确,或者我是在错误的方向上接近它?


投票迁移到 http://programmers.stackexchange.com/。 - Phil
3个回答

0
你做错了。在你的过程式示例中,你是逐行迭代数据;在你的面向对象示例中,如果你将它们视为数组然后打印它们,你会按列遍历数据。与其将数据分成单独的id和标题,我会将它们视为一组(即类似于你在过程式版本中所做的)-一个id与一个标题相对应,而不是其他id,对吧?
因此,例如,你可能有一个成员变量。
private $texts = array();

然后在你的构造函数中,执行:

while ($info_row = $info->fetch_array()) {
    $text = array(
        'id' => $info_row['info_id'],
        'title' => $info_row['info_title']
    );
    $this->texts[] = $text;
}

然后提供一种方法来获取这个数组的数组:

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

最后,您可以像在过程式示例中那样迭代它:
<?php
$display = new InfoTest();
foreach ($display->getTexts() as $text) {
    ?>
    <!-- html goes here -->
    <?php echo $text['info_id']; ?>
    <!-- more html -->
    <?php echo $text['info_title']; ?>
    <!-- other html -->
    <?
}
?>

退一步说,你可以问自己这是否真的有必要。使用过程式 PHP 并没有本质上的问题——如果它能够满足你的需求并且代码清晰易懂,那么在这里选择简单而非复杂可能更为明智。

0
在转向面向对象编程之前,我首先会将代码模块化,并开始将其分成具有相互分离逻辑的功能部分,例如数据库访问和模板化:
<?php

/**
 * infos provider
 *
 * @return array
 */
function get_infos()
{
    $infos = array();
    $dbc = get_dbc();
    $info = mysqli_query($dbc, "SELECT info_id, info_title FROM text") or die("Error: ".mysqli_error($dbc));
    while ($info_row = mysqli_fetch_array($info))
    {
        $infos[] = (object) $info_row;
    }
    return $infos;
}

foreach(get_infos() as $info)
{
?>
<div style="width: 100%;">
     <div style="float: left;">
          <?php echo $info->info_id; ?>
     </div>
     <div style="float: left;">
          <?php echo $info->info_title; ?>
     </div>
     <div style="clear: both;"></div>
</div>
<?php } ?>

然后将与数据库相关的函数移动到它自己的文件中,以将其与“模板”解耦。完成后,您可以考虑进一步重构步骤。我建议阅读以下内容(仅与命名框架无关):当平面PHP遇见Symfony


0
因为 info id 在你的对象中是一个数组,相应的获取值的函数应该采取偏移量。或者更好的方法是,查看实现迭代器的类,这样你就可以在对象上进行 foreach 操作了。

@hakre 这只是遍历公共属性。我认为Matthew正在讨论实现IteratorAggregate(或类似)以提供对内部数组的迭代。 - Phil
@Phil:显然,是的。这只是一个提示,它已经在某种程度上适用于对象(就像它在某种程度上适用于数组一样)。 - hakre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接