PHP将递归数组函数转换为类

时间:2011-08-13 07:21:20

标签: php json class recursive-query

我有一个简单的递归数组函数,如下所示:

function recursive_array($results) {
    global $DBH;
    if (count($results)) {
        echo $res - > Fname;
        foreach($results as $res) {
            $STH = $DBH - > query("SELECT FID,FParentID,Fname FROM list WHERE FParentID  = ".$res - > FID."");
            $fquerycount = $STH - > rowCount();
            $STH - > setFetchMode(PDO::FETCH_OBJ);
            recursive_array($STH);
        }
    }
}


$FID = isset($_GET['FID']) ? $_GET[' FID'] : 0;
$STH = $DBH - > query("SELECT FID,FParentID,Fname FROM list WHERE FParentID ='0' ");
$STH - > setFetchMode(PDO::FETCH_OBJ);
recursive_array($STH);

我还创建了一个简单的查询类,如下所示:

class queryloop {
    function __construct($args) {
        global $DBH;
        $table = $args['tbl'];
        if (array_key_exists('orderby', $args)): $orderby = 'ORDER BY '.$args['orderby'];
        else: $orderby = '';endif;
        if (array_key_exists('groupby', $args)): $groupby = 'GROUP BY '.$args['groupby'];
        else: $groupby = '';endif;
        if (array_key_exists('start', $args)): unset($orderby);$start = $args['start'].' , ';
        else: $start = '';endif;
        if (array_key_exists('limit', $args)): $limit = 'LIMIT '.$start.' '.$args['limit'];
        else: $limit = '';endif;
        // UNSET the previously used array keys so they are not use again to create the query string
        unset($args['tbl']);
        unset($args['orderby']);
        unset($args['groupby']);
        unset($args['start']);
        unset($args['limit']);
        // Checks if args still an array after UNSET above.  If not empty create the query string
        if (!empty($args)): foreach($args as $k = > $v): $querystr. = 'AND '.$k.' = \''.$v.'\'';endforeach;
        // If args array empty return empty query string
        else: $querystr = '';endif;$STH = $DBH - > query("SELECT * FROM ".$table." WHERE key = '".KEY."'  ".$querystr."  ".$groupby." ".$orderby."  ".$limit." ");
        if ($STH): $STH - > setFetchMode(PDO::FETCH_OBJ);
        while ($row = $STH - > fetch()): foreach($row as $key = > $val):
        // check if value is numeric //        
        if (is_numeric($row - > $key)): $data[$row - > ID][$key] = $row - > $key;
        // check if value is array //
        elseif(is_array($row - > $key)): $data[$row - > ID][$key] = $row - > $key;
        // check if value is not numeric or array convert to html entities //
        else: $data[$row - > ID][$key] = htmlentities($row - > $key);endif;endforeach;endwhile;$this - > data = json_encode($data); // return json array if data
        else: $this - > data = ''; // return 'null' if no data
        endif;
    }
}

$args = array('tbl' = > 'atable', 'limit' = > '5', 'start' = > '200', 'orderby' = > 'ID DESC');
$loop = new queryloop($args) // run the loop etc.

如何将我的递归数组转换为类queryloop之类的东西,以便我可以“拉出”json endoded数据我知道这(下面)是完全错误但是我做什么我无法得到正确形成的json数组甚至可以从我下面尝试过的课程中返回任何内容。帮助会非常感激。提前谢谢。

class recloop {
    function __construct() {}

    function recursive_array($results) {
        global $DBH;
        if (count($results)) {
            foreach($results as $res) {
                echo $res - > Name;
                $STH = $DBH - > query("SELECT * FROM atable WHERE ParentID  = ".$res - > ID."");
                $fquerycount = $STH - > rowCount();
                $STH - > setFetchMode(PDO::FETCH_OBJ);
                recursive_array($STH);
            }
        }
    }

    function recursive_start() {
        global $DBH;
        $ID = isset($_GET['ID']) ? $_GET['ID'] : 0;
        $STH = $DBH - > query("SELECT * FROM atable WHERE ParentID  = '".$ID."' ");
        $STH - > setFetchMode(PDO::FETCH_OBJ);
        recursive_array($STH);
    }
}

1 个答案:

答案 0 :(得分:2)

  

如何将我的递归数组转换为类queryloop之类的东西,以便我可以“拉出”json endoded数据我知道这(下面)是完全错误但是我做什么我无法得到正确形成的json数组甚至可以从我下面尝试过的课程中返回任何内容。帮助会非常感激。提前谢谢。

要回答你的问题,我会说如果你将你的例程封装到对象中或者没有那么多,那就不具体了,但是你要注意每个对象只是为了一个目的。例如:

  • 一个对象是从数据库中提取数据。
  • 一个对象/复合/数组是表示数据的数据结构。
  • 一个对象或函数正在接管作业以将数据转换/编码为json。

在您的代码中,我看到您现在只运行SQL查询。从数据库服务器获取的数据根本不存储在返回变量中,而是在递归处理时直接使用它。我假设您出于调试原因这样做。

所以实际的问题是,你想做什么?你写的是你想要将一个对象编码为json输出,这对于json_encodeDocs是完全可能的,但我认为你引用了一些特定的数据,比如最大parentId的实体(数据)或其他东西。

以下是一些基于您的代码的模拟代码,用于读取目的(未经测试,不得满足您的需求),可通过递归使用ID指定的所有父对象。递归一直受到批评,因为这会导致运行大量查询 - 此外还有创建无限循环的风险,这会导致递归堆栈溢出 - 然后程序崩溃。

为了处理它,这是绑定到数据库设计(应该在设计代码之前完成,我不知道你的数据库设计也不知道你真正想做什么,所以我不能添加对此的假设)。因此,以下代码仅处理已查询的对象,同时仍使用递归作为查询数据库的策略。

对于实际的数据结构,我选择了一个普通的旧PHP对象数组,由数据库中的ID字段键入(我假设它存在于每个记录中):

/**
 * HTTP Get Parameter (Input)
 */
class HTTPGetParameter {
    private $name;
    private $default;
    public function __construct($name, $default = '') {
        $this->name = (string) $name;
        $this->default = (string) $default;   
    }
    /**
     * @return string
     */
    public function getValue()
    {
        return isset($_GET[$name]) ? $_GET[$name] : $this->default;
    }
    /**
     * @return int
     */
    public function getValueInt()
    {
        return (int) $this->getValue();
    }
    /**
     * @link http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring
     */
    public function __toString()
    {
        return $this->getValue();
    }
}

/**
 * Data Provider
 */
class PDODataProvider
{
    private $pdo;
    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }
    /**
     * @return array
     */
    public function findAllATableParents($id)
    {
        return $this->findAllOn('atable', 'ParentID', $id);
    }
    public function findAllBTableParents($id)
    {
        return $this->findAllOn('btable', 'ParentID', $id);
    }
    private function findAllOn($table, $field, $id)
    {
        $id = (int) $id;

        $objects = array();

        $sql = sprintf("SELECT * FROM %s WHERE %s  = '%d'", $table, $field, $id);
        $pdoStatement = $this->pdo->query($sql);
        $pdoStatement->setFetchMode(PDO::FETCH_OBJ);

        foreach($pdoStatement as $parent)
        {
             $parentId = $parent->ID;

             # parents that had been queried are skipped
             if (isset($objects[$parentId]))
                 continue;

             $objects[$parentId] = $parent;

             # add parent objects by recursion
             $objects += $this->findAllParents($parentId);
        }
        return $objects;
    }
}


/**
 * main
 */
$data = new PDODataProvider($DBH);

$id = new HTTPGetParameter('ID', 0);

$objects = $data->findAllParents($id->getValueInt());

echo json_encode($objects);

我希望这个例子对你回答你的问题很有帮助。