0

I have the following function to order a multidimensional array by values but now the application is in PHP 7 and create_function()is deprecated (as of PHP 7.2.0., relying on this function is highly discouraged).

I need to convert the create_function() to an anonymous php function, but I can`t do it.

Could anyone point me in the right direction ?

The following is an array example:

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
        )

)

This is the original orderBy function (using a deprecated method 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);       
        }
}

So, if I use this:

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

Or this:

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

Everything work as expected, except for PHP warnings, like "Function create_function() is deprecated in " ....

So, i am trying to fix the function to compile with PHP 7. The original function was extracted from here:

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

Thanks.

  • Possible duplicate: [php-7-2-function-create-function-is-deprecated](https://stackoverflow.com/questions/48161526/php-7-2-function-create-function-is-deprecated) – jibsteroos Oct 03 '19 at 07:53
  • Thanks for reply @jib. Yes, is a similar case. It`s just i don´t know how to proceed. – Dharma Web Studio Oct 03 '19 at 08:01

1 Answers1

0

Using an anonymous function (closure), guess you'd end up with something like:

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

The use statement allows the anonymous function access to $fnBody (pulls it into its scope)

jibsteroos
  • 1,366
  • 2
  • 7
  • 13
  • I edit my question, to explain the scenario in a better way. Unfortunately I continue to walk like a blind man. I do tests without understanding well what I am doing and without having a successful result. I will be studying and reading documentation the following hours. :-). Thanks for your reply once again @jibsteroos. – Dharma Web Studio Oct 03 '19 at 09:01
  • You replaced: `$sortFn = create_function('$a,$b', $fnBody);` with the code I suggested? – jibsteroos Oct 03 '19 at 09:04
  • Once again, thanks for reply and look into this. Yes i replace those lines. It does not fail, but it does not working as expected. Simple do not return the ordered array as it should. But it does not return errors either. – Dharma Web Studio Oct 04 '19 at 08:05