Передайте код функции создания анонимной функции для компиляции PHP 7

У меня есть следующая функция для упорядочения многомерного массива по значениям, но теперь приложение находится в PHP 7, а create_function()устарело (начиная с PHP 7.2.0, полагаться на эту функцию крайне не рекомендуется).

Мне нужно преобразовать create_function() в анонимную функцию php, но я не могу этого сделать.

Может ли кто-нибудь указать мне в правильном направлении?

Ниже приведен пример массива:

Array
(
    [120] => Array
        (
            [product_id] => 120
            [actual_price] => 176.0000
            [original_price] => 5000.0000
            [release_date] => 2013-02-26
            [in_collection] => 1
        )

    [116] => Array
        (
            [product_id] => 116
            [actual_price] => 94.0000
            [original_price] => 5250.0000
            [release_date] => 2013-11-29
            [in_collection] => 0
        )

    [119] => Array
        (
            [product_id] => 119
            [actual_price] => 87.0000
            [original_price] => 12000.0000
            [release_date] => 2011-11-23
            [in_collection] => 0
        )

    [118] => Array
        (
            [product_id] => 118
            [actual_price] => 145.0000
            [original_price] => 5000.0000
            [release_date] => 2012-06-12
            [in_collection] => 1
        )

    [117] => Array
        (
            [product_id] => 117
            [actual_price] => 117.0000
            [original_price] => 5000.0000
            [release_date] => 2013-05-31
            [in_collection] => 1
        )

)

Это исходная функция orderBy (с использованием устаревшего метода create_function)

function orderBy(&$ary, $clause, $ascending = true) {
        $clause = str_ireplace('order by', '', $clause);
        $clause = preg_replace('/\s+/', ' ', $clause);
        $keys = explode(',', $clause);
        $dirMap = array('desc' => 1, 'asc' => -1);
        $def = $ascending ? -1 : 1;

        $keyAry = array();
        $dirAry = array();
        foreach($keys as $key) {
            $key = explode(' ', trim($key));
            $keyAry[] = trim($key[0]);
            if(isset($key[1])) {
                $dir = strtolower(trim($key[1]));
                $dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
            } else {
                $dirAry[] = $def;
            }
        }


        $fnBody = '';
        for($i = count($keyAry) - 1; $i >= 0; $i--) {
            $k = $keyAry[$i];
            $t = $dirAry[$i];
            $f = -1 * $t;
            $aStr = '$a[\''.$k.'\']';
            $bStr = '$b[\''.$k.'\']';
            if(strpos($k, '(') !== false) {
                $aStr = '$a->'.$k;
                $bStr = '$b->'.$k;
            }

            if($fnBody == '') {
                $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";               
            } else {
                $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
                $fnBody .= "}\n";
                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
            }
        }

        if($fnBody) {
            $sortFn = create_function('$a,$b', $fnBody);
            usort($ary, $sortFn);       
        }
}

Итак, если я использую это:

orderBy($product_data, 'original_price',  true);

Или это:

orderBy($product_data, 'in_collection',  true);

Все работает, как и ожидалось, за исключением предупреждений PHP, например, "Функция create_function() устарела в " ....

Итак, я пытаюсь исправить функцию для компиляции с PHP 7. Исходная функция была извлечена отсюда:

https://www.php.net/manual/en/function.usort.php#89977

Спасибо.


person user3670549    schedule 03.10.2019    source источник
comment
Возможный дубликат: php-7-2-function-create-function-is -устарело   -  person jibsteroos    schedule 03.10.2019
comment
Спасибо за ответ @jib. Да, аналогичный случай. Просто я не знаю, как поступить.   -  person user3670549    schedule 03.10.2019


Ответы (1)


Используя анонимную функцию (закрытие), угадайте, что вы получите что-то вроде:

$sortFn = function($a, $b) use ($fnBody) {
   $fnBody;
};

Оператор use позволяет анонимной функции получить доступ к $fnBody (перетаскивает ее в свою область)

person jibsteroos    schedule 03.10.2019
comment
Я редактирую свой вопрос, чтобы лучше объяснить сценарий. К сожалению, я продолжаю ходить как слепой. Я делаю тесты, плохо понимая, что делаю, и не получая успешного результата. Я буду изучать и читать документацию в следующие часы. :-). Спасибо за ваш ответ еще раз @jibsteroos. - person user3670549; 03.10.2019
comment
Вы заменили: $sortFn = create_function('$a,$b', $fnBody); кодом, который я предложил? - person jibsteroos; 03.10.2019
comment
Еще раз спасибо за ответ и изучить это. Да, я заменяю эти строки. Это не терпит неудачу, но это не работает, как ожидалось. Простые не возвращают упорядоченный массив, как следует. Но и ошибок не возвращает. - person user3670549; 04.10.2019