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 | Show 2 more comments3 Answers
Reset to default 1Use 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);
});
$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$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:19if ($args & PREG_FIND_SORTMODIFIED) $sortby = fn($f) => $f['stat']['mtime'];
. – Barmar Commented Jan 27 at 16:22