【问题标题】:Calling a method on array iteration, from an object - PHP从对象调用数组迭代的方法 - PHP
【发布时间】:2015-06-19 11:34:42
【问题描述】:

我想要做的是遍历一个数组(在我的例子中是一个 MySql 结果),然后输出它,但同时也对数据做其他事情。

使用过程方法很容易做到这一点 - 只需将其放入 foreach 循环中即可。

但是,我想知道是否有一种方法可以将它集成到对象中。

因此,例如,我想将第一个字段放入会话中,我可以这样做:

<?php
    class MyClass {

        public $myArray=array();

        public function __construct() {

            //..
            //Mysql query as $stmt
            //..
            $this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);

        }

    }

    $obj=new MyClass;
    $i=0;
    foreach($obj->myArray as $row) {
        ?>
            <!-- Output HTML formatted data -->
        <?
        $_SESSION[$i]=$row['firstfield'];
        $i++;
    }
?>

但是,这会从课堂上拿走任务。

我可以在类中放置一个 foreach 循环,如下所示:

<?php
    class MyClass {

        public $myArray=array();

        public function __construct() {

            //..
            //Mysql query as $stmt
            //..
            $this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
            $i=0;
            foreach($this->myArray as $row) {
                $_SESSION[$i]=$row['firstfield'];
                $i++;
            }

        }

    }

    $obj=new MyClass;

    foreach($obj->myArray as $row) {
        ?>
            <!-- Output HTML formatted data -->
        <?
    }
?>

但是,现在我们在同一个数据集上有 2 个循环。完成相同任务的时间增加一倍。

有没有办法在数组被循环时创建一个方法来做某事?有效地使数据集只需要循环一次...

编辑

另外,忘了提一下,我无法在对象中构建 HTML 的原因是因为它将用于具有不同 HTML 布局的不同页面。

【问题讨论】:

  • 建设性反馈将不胜感激:D

标签: php arrays oop


【解决方案1】:

这个怎么样

<?php
    class MyClass {

        public $myArray=array();
        public $htm = NULL;

        public function __construct(&$format=NULL) {
            //..
            //Mysql query as $stmt
            //..
            $this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);
            $i=0;
            foreach($this->myArray as $row) {
                switch ($format) {
                  case 'Page1' :
                     $this->htm .= $this->format1($row);
                     break;
                  case 'Page2' :
                     $this->htm .= $this->format2($row);
                     break;
                  default:
                     $this->htm .= $this->format_default($row);
                }
                $_SESSION[$i]=$row['firstfield'];
                $i++;
            }
        }

        private function format1($row) {
           return // formatted html
        }

        private function format2($row) {
           return // formatted html
        }

        private function format_default($row) {
           return // formatted html
        }

    }

    $obj=new MyClass('Page1');

    echo $obj->htm;
?>

或者,您可以根据需要的格式使用尽可能多的子类对 MyClass 进行子类化。

class myBaseClass {

    public $myArray=array();

    public function __construct() {

        //..
        //Mysql query as $stmt
        //..
        $this->myArray=$stmt->fetchAll(PDO::FETCH_ASSOC);

    }

}

class format1Class extends myBaseClass
{
    public $htm;

    public function __construct() {
        parent::_construct();

        $i=0;
        foreach($this->myArray as $row) {
            $this->htm .= // format specific to this class

            $_SESSION[$i]=$row['firstfield'];
            $i++;
        }
    }
}

class format2Class extends myBaseClass
{
    public $htm;

    public function __construct() {
        parent::_construct();

        $i=0;
        foreach($this->myArray as $row) {
            $this->htm .= // format specific to this class

            $_SESSION[$i]=$row['firstfield'];
            $i++;
        }
    }
}

现在取决于您在实例化所需类的任何脚本中所需的格式。

$obj = new format2Class();

echo $obj->htm;

【讨论】:

  • 对不起,我应该提到,这是因为该对象被用于具有不同 html 布局的不同页面上。我会更新我的问题...
  • 好的,现在尝试我的第二次尝试,我已经掌握了所有相关信息
  • 是的,我想这是唯一的方法......@RyanVincent 提到了观察者模式,但我个人认为这对于我需要的东西有点 OTT......我试图保留所有 HTML格式化我的对象,但我想我已经被打败了大声笑......谢谢
  • 好吧,您总是可以考虑使用特定于 HTML 格式的 X 类对 MyClass 进行子类化。然后你只需为你想要的页面布局实例化正确的类。
  • 查看替代建议,也许更符合您的要求
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
相关资源
最近更新 更多