简体   繁体   中英

Strict Standards: Only variables should be passed by reference in… - error line

I have error like this:

Strict Standards: Only variables should be passed by reference in /file.php in line 100

In file.php line look like this:

foreach($filelist as $value => $file) {
    // ABOVE LINE IS LINE 100
    if(in_array(end(explode(".", $file)), $extensions)&&is_file($dir.$file)) { $c++; }
    if(IsSet($_GET['start'])) {
        $nav = $_GET['start'];
    } else {
        $nav = "0";
    }
    if(($c > $nav) && ($c < $nav+($pagerows+1))) {
        $link = $dir . $file;
        $hlink = $http . $file;
        $ext = explode(".", $file);
        if(in_array(end($ext), $extensions)&&is_file($link)) {
            $p++;
            if(file_exists($link)) {
                list($width, $height, $type, $attr) = getimagesize($link);
                if($height > SMALL_IMAGE_HEIGHT) {
                    $imageheight = SMALL_IMAGE_HEIGHT;
                } else {
                    $imageheight = $height;
                }

Could you help me? I found topics like this but noon have code like my code.

end accepts its parameter by reference, because it modifies the array. I. e. it moves the array iterator to the last element and returns the last element. That's why you get the warning. You can remove it, if you simply replace the line that produces the error:

if(in_array(end(explode(".", $file)), $extensions)&&is_file($dir.$file)) { $c++; }

Replace with:

$ext = explode(".", $file); 
if(in_array(end($ext), $extensions)&&is_file($dir.$file)) { $c++; }

Like you did in a later part of your code.

Then you could also delete line 105 ( $ext = explode(".", $file); ), but you don't have to.

Well you could use something better to get the extension like this

$ext = strrchr($file, ".");

The only difference is this keeps the . so if $file is somefile.txt it return .txt which if you want to get rid of you could always do this

$ext = ltrim(strrchr($file, "."), '.');

For reference

http://php.net/manual/en/function.strrchr.php

strrchr — Find the last occurrence of a character in a string.

string strrchr ( string $haystack , mixed $needle )

This function returns the portion of haystack which starts at the last occurrence of needle and goes until the end of haystack.

So it just finds the last . and return that and everything after, then ltrim is just "left" trim.

PS I really dislike using explode for getting the extension, it's one of my pet peeves.

So for your particular case I would:

foreach($filelist as $value => $file) {
    $ext = ltrim(strrchr($file, "."), '.');
    if(in_array($ext, $extensions) && is_file($dir.$file)) { $c++; } 

    if(isset($_GET['start'])) { $nav = $_GET['start']; } else { $nav = "0"; }
    if(($c > $nav)&&($c < $nav+($pagerows+1))) {
    $link = $dir . $file;
    $hlink = $http . $file;

    //$ext = explode(".", $file); we've already done this no need to do it again

This way, you get the extension one time, you don't create an array for it explode , you don't move the array pointer to the end of the array end and that's about it.

UPDATE

You can compare these two using microtime to see which is faster, they are both really fast so we have to do about 100k iterations to test it, like this:

$filename = "filename.php";

$start = microtime(true);

for($i=0; $i<=100000; $i++){
    $v=explode(".", $filename);
    $ext1 = end($v);
}

echo "1. ext='$ext1' Complete ".number_format((microtime(true) - $start), 4).PHP_EOL;

$start = microtime(true);

for($i=0; $i<=100000; $i++){
    $ext2 = ltrim(strrchr($filename, '.'), '.');

}

echo "2. ext='$ext2' Complete ".number_format((microtime(true) - $start), 4).PHP_EOL;

Outputs

 1. ext='php' Complete 0.0178
 2. ext='php' Complete 0.0098
 ----------------------------
 1. ext='php' Complete 0.0237
 2. ext='php' Complete 0.0125
 ---------------------------
 1. ext='php' Complete 0.0252
 2. ext='php' Complete 0.0098
 ---------------------------
 1. ext='php' Complete 0.0190
 2. ext='php' Complete 0.0102

You can test it here online

One thing is clear, it's almost 2x faster, not that it matters much in this case. But, it never hurts to check these things. Both give equivalent results, but strrchr is easier to read, well if you know what the function does anyway. It's kind of an obscure function but it basically means str ing r ight ch a r acter.

Cheers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM