最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - How can I rewrite a function where I used "create_function()" to something like "fn()"

programmeradmin4浏览0评论

Apologies....the function is working just fine as it is, which is why I did not think any additional details were needed. (I am just trying to get rid of my deprecation warning (version 7.4) and I cannot upgrade PHP at this time) Here is the working code:

I am looking to replace the create_function() (deprecated in php) with another solution.

// Before returning check if we need to sort the results.
    if (($depth==0) && ($args & 
(PREG_FIND_SORTKEYS|PREG_FIND_SORTBASENAME|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTFILESIZE|PREG_FIND_SORTDISKUSAGE)) ) 
    {
    $order = ($args & PREG_FIND_SORTDESC) ? 1 : -1;
    $sortby = '';
    if ($args & PREG_FIND_RETURNASSOC) 
    {
    if ($args & PREG_FIND_SORTMODIFIED)  $sortby = "['stat']['mtime']";
    if ($args & PREG_FIND_SORTBASENAME)  $sortby = "['basename']";
    if ($args & PREG_FIND_SORTFILESIZE)  $sortby = "['stat']['size']";
    if ($args & PREG_FIND_SORTDISKUSAGE) $sortby = "['du']";
    }

// Sort Function(currently working, but deprecation warning.

    $filesort = create_function('$a,$b', "\$a1=\$a$sortby;\$b1=\$b$sortby; if (\$a1==\$b1) return 0; else return (\$a1<\$b1) ? $order : 0- $order;");
    uasort($files_matched, $filesort);
    }
    --$depth;
    return $files_matched;

Any assistance would be appreciated. Thanks

Apologies....the function is working just fine as it is, which is why I did not think any additional details were needed. (I am just trying to get rid of my deprecation warning (version 7.4) and I cannot upgrade PHP at this time) Here is the working code:

I am looking to replace the create_function() (deprecated in php) with another solution.

// Before returning check if we need to sort the results.
    if (($depth==0) && ($args & 
(PREG_FIND_SORTKEYS|PREG_FIND_SORTBASENAME|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTFILESIZE|PREG_FIND_SORTDISKUSAGE)) ) 
    {
    $order = ($args & PREG_FIND_SORTDESC) ? 1 : -1;
    $sortby = '';
    if ($args & PREG_FIND_RETURNASSOC) 
    {
    if ($args & PREG_FIND_SORTMODIFIED)  $sortby = "['stat']['mtime']";
    if ($args & PREG_FIND_SORTBASENAME)  $sortby = "['basename']";
    if ($args & PREG_FIND_SORTFILESIZE)  $sortby = "['stat']['size']";
    if ($args & PREG_FIND_SORTDISKUSAGE) $sortby = "['du']";
    }

// Sort Function(currently working, but deprecation warning.

    $filesort = create_function('$a,$b', "\$a1=\$a$sortby;\$b1=\$b$sortby; if (\$a1==\$b1) return 0; else return (\$a1<\$b1) ? $order : 0- $order;");
    uasort($files_matched, $filesort);
    }
    --$depth;
    return $files_matched;

Any assistance would be appreciated. Thanks

Share Improve this question edited Jan 27 at 17:13 Mark Stevens asked Jan 27 at 12:50 Mark StevensMark Stevens 112 bronze badges 7
  • 2 You code is incomplete. Where do $sortby an $order come from? To check, whatever answer we produce, it would be nice to have code that can actually run. Can you please edit your question and show us a minimal, workable example? It also seems that this function is quite basic. It almost does the same as the spaceship operator, apart from these variables that come out of nowhere. – KIKO Software Commented Jan 27 at 13:03
  • This can probably get an easy rewrite but as @KIKOSoftware already said, you need to provide a few more details. The part that really triggers me is the dynamic variable naming using $sortby. You should get rid of that too, in my opinion (maybe replace it with an array, passed as an argument). – AymDev Commented Jan 27 at 13:19
  • Apologies....the function is working just fine as it is, which is why I did not think any additional details were needed. (I am just trying to get rid of my deprecation warning (version 7.4) and I cannot upgrade PHP at this time) Here is the working code: – Mark Stevens Commented Jan 27 at 15:26
  • I did my best to include more in the question. Sorry all...this is my first time posting a question. – Mark Stevens Commented Jan 27 at 15:35
  • 2 Use anonymous functions like if ($args & PREG_FIND_SORTMODIFIED) $sortby = fn($f) => $f['stat']['mtime'];. – Barmar Commented Jan 27 at 16:22
 |  Show 2 more comments

3 Answers 3

Reset to default 1

Use arrow functions to extract the appropriate field from each file depending on the sorting option.

In the actual comparison function you can use the spaceship operator <=> to compare the fields and return a result appropriate for uasort(). This can then be multiplied by $order to reverse it if necessary.

if (($depth==0) && ($args & 
                    (PREG_FIND_SORTKEYS|PREG_FIND_SORTBASENAME|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTFILESIZE|PREG_FIND_SORTDISKUSAGE)) ) 
{
    $order = ($args & PREG_FIND_SORTDESC) ? -1 : 1;
    if ($args & PREG_FIND_RETURNASSOC) 
    {
        if ($args & PREG_FIND_SORTMODIFIED) {
            $sortby = fn($f) => $f['stat']['mtime'];
        } elseif ($args & PREG_FIND_SORTBASENAME) {
            $sortby = fn($f) => $f['basename'];
        } elseif ($args & PREG_FIND_SORTFILESIZE){
            $sortby = fn($f) => $f['stat']['size'];
        } elseif ($args & PREG_FIND_SORTDISKUSAGE) {
            $sortby = fn($f) => $f['du'];
        }
    } else {
        $sortby = fn($f) => $f; // default to using the value as is
    }
    uasort($files_matched, fn($a, $b) => $order * ($sortby($a) <=> $sortby($b)));
}

Different approach:

Map the sort field first and then use array_multisort(). uasort() was only in use to access the sort field.

array_multisort(array_column($data, 'field'), SORT_DESC, $data);

This also works two levels deep:

array_multisort(array_column(array_column($data, 'extra'), 'field'), SORT_DESC, $data);

And you can prepare the first array at the place where you currently have the expressions which field to use for sorting, SORT_DESC / SORT_ASC you can use as the second parameter and the third parameter $data is what you actually sort ($files_data array in your example).


// Before returning check if we need to sort the results.
if (($depth==0) && ($args &
        (PREG_FIND_SORTKEYS|PREG_FIND_SORTBASENAME|PREG_FIND_SORTMODIFIED|PREG_FIND_SORTFILESIZE|PREG_FIND_SORTDISKUSAGE)) )
{
    $order = ($args & PREG_FIND_SORTDESC) ? SORT_ASC : SORT_DESC;
    $sortby = $files_matched;
    if ($args & PREG_FIND_RETURNASSOC)
    {
        if ($args & PREG_FIND_SORTMODIFIED)
            $sortby = array_column(array_column($sortby, 'stat'), 'mtime');
        if ($args & PREG_FIND_SORTBASENAME)
            $sortby = array_column($sortby, 'basename');
        if ($args & PREG_FIND_SORTFILESIZE)
            $sortby = array_column(array_column($sortby, 'stat'), 'size');
        if ($args & PREG_FIND_SORTDISKUSAGE)
            $sortby = array_column($sortby, 'du');
    }

    array_multisort($sortby, $order, $files_matched);
}
# ...

First I'd transform the sorting keys to an array:

$sortby = [];
if ($args & PREG_FIND_RETURNASSOC) {
    if ($args & PREG_FIND_SORTMODIFIED)  $sortby = ['stat', 'mtime'];
    if ($args & PREG_FIND_SORTBASENAME)  $sortby = ['basename'];
    if ($args & PREG_FIND_SORTFILESIZE)  $sortby = ['stat', 'size'];
    if ($args & PREG_FIND_SORTDISKUSAGE) $sortby = ['du'];
}

Then use uasort with a closure using the sorting and ordering variables. You loop through $sortby to get the final values you want to compare, then do the comparison using $order and the spaceship operator:

uasort($files_matched, function ($a, $b) use ($sortby, $order) {
    $aValue = $a;
    $bValue = $b;
    foreach ($sortby as $key) {
        $aValue = $aValue[$key];
        $bValue = $bValue[$key];
    }
    
    return $order * ($aValue <=> $bValue);
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论