«Приведение» запроса к массиву - PullRequest
0 голосов
/ 25 февраля 2012

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

Что мне интересно, если есть способ«преобразовать» или преобразовать результат запроса, который будет обрабатываться как ассоциативный массив вместо ресурса, без необходимости циклически перебирать результаты запроса.Кстати, в настоящее время мы находимся в MS SQL без планов перехода на другую СУБД.

РЕДАКТИРОВАТЬ: Вот мой код (немного изменен с производства, но вы получите суть).

function phpSelect($varName, &$queryName,$valueField, $displayField, $selectedValue, $returnFullSelect = true, $additionalAttributes = "", $distinctOnly = false){
/**
 * Creates select dropdown from SQL results and selects given value
 */
    $thisSelect = '';
    $resultsArray = array();

    //If they request a full tag, start it here//
    if($returnFullSelect){
        $thisSelect = "<select name=\"$varName\" id=\"$varName\" " .$additionalAttributes .'>
        ';
        $thisSelect .= '    <option value=""> </option>
        ';// clean up - decide if we should put a blank option first or not
    }

    if(is_resource($queryName) ){  // use this for queries
        if( mssql_num_rows($queryName) == 0) return '<!-- Query passed was empty -->';//If the query is empty, just return empty string
        mssql_data_seek($queryName,0);
        //new dBug($queryName);
        $row_thisQuery = mssql_fetch_assoc($queryName);
        $totalRows_thisQuery = mssql_num_rows($queryName);


        do {
            $tempAlreadyExists = array_search(trim(strtoupper($row_thisQuery[$valueField])),$resultsArray);
            if(!$distinctOnly or !is_numeric($tempAlreadyExists) ){ // if Distinct is set to false or this value is not already in the array, add to the array, otherwise, skip it
                $thisOption = '<option value="' .$row_thisQuery[$valueField] .'"';
                if( is_string($selectedValue) ){ //perform case insensitive check
                    if( strtoupper( trim($row_thisQuery[$valueField]) ) == strtoupper( trim($selectedValue) ) ){
                        $thisOption .=" selected";
                    }
                } else {
                    if($row_thisQuery[$valueField] == $selectedValue){
                        $thisOption .=" selected";
                    }
                }
                $thisOption .='>';
                $thisOption .= $row_thisQuery[$displayField];
                $thisOption .= '</option>
                    ';
                $thisSelect .= $thisOption;

                array_push($resultsArray,trim( strtoupper($row_thisQuery[$valueField]) )  );
            } //End checking for distinct values
        } while ($row_thisQuery = mssql_fetch_assoc($queryName)); 

        if($returnFullSelect){
            $thisSelect .= '</select>
            ';
        }
        return $thisSelect;

    } elseif( is_array($queryName) ){  // use this for arrays

        foreach ($queryName as $i => $values) {
            $thisOption = '<option value="' .$values[$valueField] .'"';
            if($values[$valueField] == $selectedValue){
                $thisOption .=" selected";
            }
            $thisOption .='>';
            $thisOption .= $values[$displayField];
            $thisOption .= '</option>
                ';
            $thisSelect .= $thisOption;


        }


        //If they request a full tag, end it here//
        if($returnFullSelect){
            $thisSelect .= '</select>
            ';
        }
        return $thisSelect;
    } else { // didn't pass a query or array, return failure
        return false;   
    }
}

Ответы [ 4 ]

4 голосов
/ 25 февраля 2012

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

Даже если бы была функция mssql_fetch_all_rows_as_array(), вы бы все равноза кулисами делайте итерации по набору результатов, так что вам не стоит бояться делать эту итерацию в своем коде PHP.Если вам часто приходится делать это в своем коде, подумайте над тем, чтобы написать вспомогательную функцию, чтобы вам не приходилось писать (и отлаживать) один и тот же код во многих местах.

1 голос
/ 25 февраля 2012

Вы могли бы рассмотреть что-то вроде этого (это грубое и чисто концептуальное определение):

interface DropdownDataProvider
{
    public hasNext();
    public getNext();
}

class DBDataProvider implements DropdownDataProvider
{
    // ...
}


class ArrayDataProvider implements DropdownDataProvider
{
    // ...
}

и, наконец, ваш выпадающий список можно смоделировать следующим образом:

class Dropdown
{
    public function __construct(DropdownDataProvider $provider)
    {
        // ...
    }

    // ...
}

Такой подход позволил бы вам получить доступ к результату запроса «стиль курсора», как и предполагалось, без каких-либо проблем с упаковкой вещи в соответствующие массивы. Это также позволит вам менять новые выпадающие источники данных без особых проблем.

Надеюсь, это поможет.

0 голосов
/ 25 февраля 2012

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

Таким образом, даже если вы получите какой-нибудь «магический» метод, который, по-видимому, «приведёт» ваш ресурс к массиву, БУДЕТ внутри цикл.

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

0 голосов
/ 25 февраля 2012

Без разбора здесь нет никакого способа разыграть все это, однако это то, как вы бы сделали это зацикливанием, как правило, так делают все.

$arr=array();
while($row = mssql_fetch_assoc($result))
    $arr[]=$row;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...