I am trying to sort a list of partners either by Place (alphabetically) or german postcode.

The code I have come up with works fine locally using XAMPP but as soon as I upload it I get the following error:

Parse error: syntax error, unexpected '&', expecting T_VARIABLE or '$' in /mnt/am2/06/739/00000010/htdocs/fmxf/sortCA.php on line 17

as you can see at http://www.rattenfaenger-hameln.de/fmxf/sortCA.php

I have tried the same script on 3 different webservers, to no avail.

Line 17 reads

foreach($arr as $k => &$e){

and is in a function. I am calling this function by using create_function.

The full script looks like this:

<form name="form1" method="post" action="<? $_SERVER['PHP_SELF']?>">
<input type="hidden" name="stage" value="process">
  <p>
    <select name="sorter" size="1" id="sorter">
	<option value="" selected>Sortiere nach...</option>
      <option value="name">Ort</option>
      <option value="plz">PLZ</option>
      <option value="strasse">Straße</option>
    </select>
</p>
    <input type="submit" name="Submit" value="Senden">
</form>
<?
//--------------The function
function sortByFunc(&$arr, $func){
echo "calling now<br><br>";
$tmpArr = array();
 foreach($arr as $k => &$e){
  $tmpArr[] = array('f' => $func($e), 'k' => $k, 'e' =>&$e);
  }
 sort($tmpArr);
 $arr = array();
 foreach($tmpArr as &$fke) {
  $arr[$fke['k']] = &$fke['e'];
 }
}
//-----------------The array I am trying to sort
$arr = array(
 1 => array('name'=>"Dresden", 'plz'=>"01307", 'strasse'=>"Dürerstraße 49", 'fon'=>"+49 (0351) 44 967 12", 'link'=>"http://www.car-akustik.de/dresden/stand_dr.htm"),
 2 => array('name'=>"Riesa", 'plz'=>"01591", 'strasse'=>"Stahlwerker Straße 2", 'fon'=>"+49 (03525) 73 44 69", 'link'=>"http://www.car-akustik.de/riesa/stand_rie.htm"),
 3 => array('name'=>"Halle/Saale", 'plz'=>"06126", 'strasse'=>"Nietlebener Straße 11", 'fon'=>"+49 (0345) 55 122 47", 'link'=>"http://www.car-akustik.de/halle/stand_ha.htm"),
 4 => array('name'=>"Gera", 'plz'=>"07548", 'strasse'=>"Hofer Str. 2", 'fon'=>"+49 (0365) 80 074 12", 'link'=>"http://www.car-akustik.de/gera/stand_gera.htm"),
 5 => array('name'=>"Zwickau", 'plz'=>"08064", 'strasse'=>"Lengenfelder Str. 6", 'fon'=>"+49 (0375) 77 888 97", 'link'=>"http://www.car-akustik.de/zwickau/stand_zwickau.htm"),
 6 => array('name'=>"Rathenow", 'plz'=>"14712", 'strasse'=>"Sandweg 11", 'fon'=>"+49 (03385) 54 93 15", 'link'=>"http://www.car-akustik.de/rathenow/stand_rathenow.htm"),
 7 => array('name'=>"Mainz-Kastel", 'plz'=>"55252", 'strasse'=>"Philippsring 18", 'fon'=>"+49 (06134) 46 64", 'link'=>"http://www.car-akustik.de/mainz/stand_mainz.htm"),
 8 => array('name'=>"Stuttgart-Bad Cannstadt", 'plz'=>"70374", 'strasse'=>"Hofener Str. 140", 'fon'=>"+49 (0711) 55 905 20", 'link'=>"http://www.car-akustik.de/stuttgart/stand_s-badcannstatt.htm"),
 9 => array('name'=>"Rosenheim", 'plz'=>"83026", 'strasse'=>"Klepperstraße 28", 'fon'=>"+49 (08031) 26 86 66", 'link'=>"http://www.car-akustik.de/rosenheim/stand_rosen.htm"),
); 

//-------------------------------assigning the value from my dropdown to a variable
$criteria=$_POST['sorter'];
echo "Suche nach ".$criteria. "<br>";
//---------------------------Call the function
sortByFunc($arr,create_function('$element','return $element['.$criteria.'];'));

//Output the newly sorted array in a table
echo '<table border="1" width=<"100%">';
foreach($arr as $key => $val) {
  echo "<tr><td><a href=". $val['link']." target='_blank'><b>car akustik ". $val['name'] ."</b></a></br>".$val['strasse']."<br/ >". $val['plz'] ." ".$val['name']."<br />".$val['fon']."</td></tr>";
}
echo '</table>';
?>

If anyone has any idea as to why it works locally but not online I would be very grateful. I changed permissions on the script.

Thanks for any help,
FG

    You might want to check the version of PHP running on the server. The pass-by-reference in foreach was quite a recent addition.

      Thanks for the super fast reply. You are probably correct.

      PHP Version 4.4.4 is the online version. My offline is 5.2.

      Do you know how I could adapt that to function with 4.4.4?

      Any help would be great. Something like this wouldn't take me very long with Flash, but PHP is a different ball game.

      Thanks again for your help!

      Flash-Genie

        The pass-by-reference change allows changes made in the temporary variable i.e.

        foreach( $array as $key => [b]&$value[/b] )
        

        to actually change the value in $array. Looking at your code you are using $tmpArr and $arr to store the changed values, and so the pass-by-reference functionality is not even used. So the solution is to remove the ampersand in the two cases of foreach.

          Hey Shrike,

          thanks again for your reply.

          I changed the function, (I removed all cases of & before a $) so it looks like:

          function sortByFunc($arr, $func){
          echo "calling now<br><br>";
          $tmpArr = array();
           foreach($arr as $k => $e){
            $tmpArr[] = array('f' => $func($e), 'k' => $k, 'e' =>$e);
            }
           sort($tmpArr);
           $arr = array();
           foreach($tmpArr as $fke) {
            $arr[$fke['k']] = $fke['e'];
           }
          }

          thus removing all the "&". The downside is I get a fatal error which looks like this:

          Cannot use [] for reading in C:\Programme\xampp\htdocs\sortCA.php(39) : runtime-created function on line 1

          Line 39 is the call to the function:

          sortByFunc($arr,create_function('$element','return $element['.$criteria.'];'));

          I'm a little lost as to what the create_function actually does, and whether the entire thing could be simplified by passing the element in the array to the function as a single parameter which "just" sorts them by in alphabetical order. Unfortunately that is out of my league.

          I have scanned google looking for a solution to sorting a mutli-dimensional array which I can then parse into a table, unfortunately without much success.

          Thanks again for your help, and I hope you can help me further.

          Much appreciated,
          Flash-G

            Shrike (and anyone else looking for a solution to sorting a multi-dimensional array and parsing the result into a table) I found a function at http://php.mirror.camelnetwork.com/manual/en/function.sort.php and simply adapted it to output the table. This is the full script for anyone looking:

            //----------------------Form to allow the user to select the sort criteria
            <form name="form1" method="post" action="<? $_SERVER['PHP_SELF'] ?>">
            <input type="hidden" name="stage" value="process">
              <p>
                <select name="sorter" size="1" id="sorter">
            	<option value="" selected>Sortiere nach...</option>
                  <option value="name">Ort</option>
                  <option value="plz">PLZ</option>
                  <option value="strasse">Straße</option>
                </select>
              </p>
                <input type="submit" name="Submit" value="Senden">
            </form>
            <?
            //----Function from http://php.mirror.camelnetwork.com/manual/en/function.sort.php
            function sortByField($multArray,$sortField,$desc=true){
                       $tmpKey='';
                       $ResArray=array();
                       $maIndex=array_keys($multArray);
                       $maSize=count($multArray)-1;
                       for($i=0; $i < $maSize ; $i++) {
                           $minElement=$i;
                           $tempMin=$multArray[$maIndex[$i]][$sortField];
                           $tmpKey=$maIndex[$i];
                           for($j=$i+1; $j <= $maSize; $j++)
                             if($multArray[$maIndex[$j]][$sortField] < $tempMin ) {
                                 $minElement=$j;
                                 $tmpKey=$maIndex[$j];
                                 $tempMin=$multArray[$maIndex[$j]][$sortField];
                             }
                             $maIndex[$minElement]=$maIndex[$i];
                             $maIndex[$i]=$tmpKey;
                       }
                       if($desc)
                           for($j=0;$j<=$maSize;$j++)
                             $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];
                       else
                         for($j=$maSize;$j>=0;$j--)
                             $ResArray[$maIndex[$j]]=$multArray[$maIndex[$j]];
            //------Output the $ResArray into a table
            				echo '<table border="1" width=<"100%">';
            foreach($ResArray as $key => $val) {
              echo "<tr><td><a href=". $val['link']." target='_blank'><b>car akustik ". $val['name'] ."</b></a></br>".$val['strasse']."<br/ >". $val['plz'] ." ".$val['name']."<br />".$val['fon']."</td></tr>";
            }
            echo '</table>'; 
                   }
            //A few arrays storing information because we can't use a database
            $arr = array(
             1 => array('name'=>"Dresden", 'plz'=>"01307", 'strasse'=>"Dürerstraße 49", 'fon'=>"+49 (0351) 44 967 12", 'link'=>"http://www.car-akustik.de/dresden/stand_dr.htm"),
             2 => array('name'=>"Riesa", 'plz'=>"01591", 'strasse'=>"Stahlwerker Straße 2", 'fon'=>"+49 (03525) 73 44 69", 'link'=>"http://www.car-akustik.de/riesa/stand_rie.htm"),
             3 => array('name'=>"Halle/Saale", 'plz'=>"06126", 'strasse'=>"Nietlebener Straße 11", 'fon'=>"+49 (0345) 55 122 47", 'link'=>"http://www.car-akustik.de/halle/stand_ha.htm"),
             4 => array('name'=>"Gera", 'plz'=>"07548", 'strasse'=>"Hofer Str. 2", 'fon'=>"+49 (0365) 80 074 12", 'link'=>"http://www.car-akustik.de/gera/stand_gera.htm"),
             5 => array('name'=>"Zwickau", 'plz'=>"08064", 'strasse'=>"Lengenfelder Str. 6", 'fon'=>"+49 (0375) 77 888 97", 'link'=>"http://www.car-akustik.de/zwickau/stand_zwickau.htm"),
             6 => array('name'=>"Rathenow", 'plz'=>"14712", 'strasse'=>"Sandweg 11", 'fon'=>"+49 (03385) 54 93 15", 'link'=>"http://www.car-akustik.de/rathenow/stand_rathenow.htm"),
             7 => array('name'=>"Mainz-Kastel", 'plz'=>"55252", 'strasse'=>"Philippsring 18", 'fon'=>"+49 (06134) 46 64", 'link'=>"http://www.car-akustik.de/mainz/stand_mainz.htm"),
             8 => array('name'=>"Stuttgart-Bad Cannstadt", 'plz'=>"70374", 'strasse'=>"Hofener Str. 140", 'fon'=>"+49 (0711) 55 905 20", 'link'=>"http://www.car-akustik.de/stuttgart/stand_s-badcannstatt.htm"),
             9 => array('name'=>"Rosenheim", 'plz'=>"83026", 'strasse'=>"Klepperstraße 28", 'fon'=>"+49 (08031) 26 86 66", 'link'=>"http://www.car-akustik.de/rosenheim/stand_rosen.htm"),
            ); 
            //-------Get the criteria
            $criteria=$_POST['sorter'];
            $SortOrder=1;
            echo "Suche nach ".$criteria. "<br>";
            sortByField($arr,$criteria,$SortOrder);
            ?>

            The snippet produces:
            http://www.rattenfaenger-hameln.de/fmxf/sortCA2.php

            Thanks again, for all the help!
            FG

              Glad you found the answer. The issue with the original script was to do with the formatting of the create_function call rather than the foreach ampersands. But it appears you have found a better solution 🙂

                By the way, the array sorting part can be done a fair bit easier with PHP's built in sorting functions.

                $arr = array(
                // snipped
                ); 
                usort( $arr, 'mySort' );
                $sort = 'plz';
                function mySort( $a, $b )
                {
                	global $sort;
                	if( $a[$sort] == $b[$sort] ) return 0;
                	return $a[$sort] < $b[$sort] ? -1 : 1;
                }
                

                All thats left is to build the HTML table. Sorry for not spotting this earlier 😉

                  Did you happen to notice the [man]array_multisort[/man] function? Seems like that's what you are trying to do.

                    It probably depends on the requirements - array_multisort is a mammoth function and in this case usort does the trick 🙂

                      bpat1434 wrote:

                      Did you happen to notice the [man]array_multisort[/man] function? Seems like that's what you are trying to do.

                      Thanks for the tip, I'm sure I can use that in the future :-D

                        I did try, but couldnt find how...until I read your sig:o

                          Write a Reply...