PHP превратить функцию рекурсивного массива в класс - PullRequest
2 голосов
/ 13 августа 2011

У меня есть простая функция рекурсивного массива, которая выглядит следующим образом:

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? Я знаю, что это (ниже) совершенно неправильно, но что бы я ни делал, я не могу получить правильно сформированный массив 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 Ответ

2 голосов
/ 13 августа 2011

Как мне превратить мой рекурсивный массив в нечто вроде класса queryloop, чтобы я мог "извлечь" данные, кодированные в json? Я знаю, что это (ниже) совершенно неправильно, но что бы я ни делал, я не могу получить правильно сформированный массив json или даже что-нибудь, чтобы вернуться из моего попытанного класса ниже Помощь будет очень признателен. Заранее спасибо.

Чтобы ответить на ваш вопрос, я бы сказал, что это не определенно, если вы инкапсулируете свои подпрограммы в объекты или не так уж много, но вы заботитесь о том, чтобы каждый объект находился там с единственной целью. Например:

  • Один объект извлекает данные из базы данных.
  • Один объект / составной / массив - это структура данных, представляющая данные.
  • Один объект или функция берет на себя работу по преобразованию / кодированию данных в json.

В вашем коде я вижу, что вы сейчас выполняете только SQL-запросы. Данные, извлеченные с сервера базы данных, вообще не сохраняются в возвращаемой переменной, они напрямую потребляются при рекурсивной обработке. Я полагаю, вы делаете это по причинам отладки.

Итак, вопрос в том, что вы хотите сделать? Вы пишете, что хотите закодировать объект в вывод json, что вполне возможно при json_encode Документах , однако я думаю, что вы ссылаетесь на некоторые конкретные данные как сущность (данные) самого parentId или что-то в этом роде.

Ниже приведен некоторый макет кода, основанный на вашем коде для целей чтения (не проверенный, не должен соответствовать вашим потребностям), который может предоставить все родительские объекты этого объекта, указанного с помощью идентификатора, с помощью рекурсии. Рекурсия подверглась критике за то, что это может привести к выполнению большого количества запросов - и, кроме того, существует риск создания бесконечного цикла, который приведет к переполнению стека рекурсии - тогда ваша программа аварийно завершает работу.

В качестве альтернативы, это связано с дизайном базы данных (что должно быть сделано до разработки кода, и я не знаю ни вашего дизайна базы данных, ни того, что вы на самом деле хотите делать, поэтому я не могу добавить предположения для этого). Поэтому следующий код заботится об уже запрошенных объектах только при использовании рекурсии в качестве стратегии для запроса вашей базы данных.

Для фактической структуры данных я выбрал массив простых старых объектов 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);

Надеюсь, этот пример поможет вам ответить на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...