34

I am trying to get an HTML-based recursive directory listing based on code here:

http://webdevel.blogspot.in/2008/06/recursive-directory-listing-php.html

Code runs fine but it throws some errors:

Strict Standards: Only variables should be passed by reference in C:\xampp\htdocs\directory5.php on line 34

Strict Standards: Only variables should be passed by reference in C:\xampp\htdocs\directory5.php on line 32

Strict Standards: Only variables should be passed by reference in C:\xampp\htdocs\directory5.php on line 34

Below is the excerpt of code:

else
  {
   // the extension is after the last "."
   $extension = strtolower(array_pop(explode(".", $value)));   //Line 32

   // the file name is before the last "."
   $fileName = array_shift(explode(".", $value));  //Line 34

   // continue to next item if not one of the desired file types
   if(!in_array("*", $fileTypes) && !in_array($extension, $fileTypes)) continue;

   // add the list item
   $results[] = "<li class=\"file $extension\"><a href=\"".str_replace("\\", "/",     $directory)."/$value\">".$displayName($fileName, $extension)."</a></li>\n";
  }
user1184100
  • 6,742
  • 29
  • 80
  • 121

4 Answers4

59

This should be OK

   $value = explode(".", $value);
   $extension = strtolower(array_pop($value));   //Line 32
   // the file name is before the last "."
   $fileName = array_shift($value);  //Line 34
haltabush
  • 4,508
  • 2
  • 24
  • 41
  • 8
    So its really just as simple as putting things outside of things... So to speak :p – Jamie Hutber Feb 27 '14 at 23:10
  • @JamieHutber Pretty much, yes. I can confirm the solution suggested works on PHP 5.3.27. – crmpicco May 15 '14 at 10:47
  • 7
    @JamieHutber Slightly more involved. The prototype for array_pop is mixed array_pop ( array &$array ) Note the ampersand in the parameter. That means the array input parameter is passed in by reference and not by value. The input array is shortened by one element, namely the element returned, the last element in the array, which is removed from the input array. The only way to modify the input argument's value is to pass it in by reference. The expression the original code cannot have its value modified because it doesn't have a named memory location with a value that can be referenced. – Jim Apr 10 '15 at 18:15
  • 10
    Having just ran into that same warning, it turns out you can keep the code inline by using extra parentheses around `explode()`: `$fileName = array_shift((explode(".", $value)));`. – spenibus Jul 25 '15 at 01:04
  • @spenibus. As of PHP 7, extra parentheses will NOT prevent the warning. See the 'Parentheses around function parameters no longer affect behaviour' section of http://php.net/manual/en/migration70.incompatible.php – Patanjali May 01 '16 at 05:02
  • Well, in obvious cases like that, you can always tell PHP to suppress messages by using "@" in front of the function. `$fileName = @array_shift(explode(".", $value));` It may not be one of the best programming practices to suppress all errors this way, but in certain cases (like this one) it comes handy and is acceptable. As result, I am sure your friend SysAdmin will be pleased with a less polluted "error.log". ;) – Julio Marchi Dec 08 '16 at 22:06
25

array_shift the only parameter is an array passed by reference. The return value of explode(".", $value) does not have any reference. Hence the error.

You should store the return value to a variable first.

    $arr = explode(".", $value);
    $extension = strtolower(array_pop($arr));   
    $fileName = array_shift($arr);

From PHP.net

The following things can be passed by reference:

- Variables, i.e. foo($a)
- New statements, i.e. foo(new foobar())
- [References returned from functions][2]

No other expressions should be passed by reference, as the result is undefined. For example, the following examples of passing by reference are invalid:

Simon Mathewson
  • 713
  • 6
  • 20
Shiplu Mokaddim
  • 56,364
  • 17
  • 141
  • 187
3

I had a similar problem.

I think the problem is that when you try to enclose two or more functions that deals with an array type of variable, php will return an error.

Let's say for example this one.

$data = array('key1' => 'Robert', 'key2' => 'Pedro', 'key3' => 'Jose');

// This function returns the last key of an array (in this case it's $data)
$lastKey = array_pop(array_keys($data));

// Output is "key3" which is the last array.
// But php will return “Strict Standards: Only variables should 
// be passed by reference” error.
// So, In order to solve this one... is that you try to cut 
// down the process one by one like this.

$data1  = array_keys($data);
$lastkey = array_pop($data1);

echo $lastkey;

There you go!

2

Instead of parsing it manually it's better to use pathinfo function:

$path_parts = pathinfo($value);
$extension = strtolower($path_parts['extension']);
$fileName = $path_parts['filename'];