I have added 3 radio buttons to a form (no errors prior to this) for option to sort fetch_array result by field. I assume this is best done from the array but am making no progress - the results of $name,print_r($array) and tables are correct but no sorting.
This Notice appears: **Uninitialized string offset: **0 in C:........on line 78
from this extract

<form method="post" name="search" action="workingjoinIDtest.php"/>
        <font family = "arial,verdana,sans-serif" color="#3F7cef"size="4"/>Enter Ship Name or IMO</font>
        <input type="text"  name="name" size="25" maxlength ="35"/>
        <input type="image" name="submit" src="texts/cooltext591383228.png" onmouseover="this.src='texts/cooltext591383228MouseOver.png';" onmouseout="this.src='texts/cooltext591383228.png';" alt="search"><br/> 
        <font family = "arial,verdana,sans-serif" color="#3F7cef"size="4">
        <p><label><input type="radio" name="sequence" value="alpha" checked="yes">Sort A-Z</p>
        <p><label><input type="radio" name="sequence" value="tons">Sort by GRT</p>
        <p><label><input type="radio" name="sequence" value="built">Sort by Year Built</p></font>        
</form>
<div class="printarea"/>         <!--line 43 -->              
<?php                                    //4 MySQL queries-allnames,launch,fate,imocode
if (isset($_POST['name'])) $name = ($_POST ['name']);
else $name = "no name entered";                     //display "no name entered"
if($name =="")                              //if submit pressed with no name entered
{
echo "<p><font color='red' size='6px'>You have not entered a name</font></p>";
exit;
echo"<br />";
}
require_once 'dbconnect.php';
  $name = strtoupper($name);
  $name = strip_tags($name);
  $name = trim ($name); 
  $name = mysql_real_escape_string($name);        // line 57                
$query = "(SELECT * FROM launch JOIN allnames ON launch.id=allnames.id JOIN fate ON fate.id=allnames.id JOIN imocode ON imocode.id=fate.id WHERE name1 LIKE '$name%' OR name2 LIKE '$name%' OR name3 LIKE '$name%' OR name4 LIKE '$name%' OR name5 LIKE '$name%' OR name6 LIKE '$name%' OR name7 LIKE '$name%' OR name8 LIKE '$name%' OR name9 LIKE '$name%' OR name10 LIKE '$name%' OR name11 LIKE '$name%' OR name12 LIKE '$name%'OR name13 LIKE '$name%' OR name14 LIKE '$name%' OR name15 LIKE '$name%'OR name16 LIKE '$name%' OR name17 LIKE '$name%')UNION(SELECT * FROM launch JOIN allnames ON launch.id=allnames.id JOIN fate ON fate.id=allnames.id JOIN imocode ON imocode.id=fate.id WHERE code LIKE '%$name%')";
$result = mysql_query($query);
if (!$result) die ("Database access failed: " . mysql_error());
$rows=mysql_num_rows($result);
echo "<font color='#3F7cef'size='4'/>You searched for:</font>";
echo "<p>";                              //<br /> justifies left and leaves no spaces
echo "<font color='#3F7cef'size='6'>";
require_once "fix_it.php";                      // works equally with name and code input
echo fix_it($name); 
echo "</font>";
if (mysql_num_rows($result)== 0)                    //line 68
echo "<p><font color='red'size='6px'>No data found for your request. Try a different query</font>";
while($row = mysql_fetch_array($result)){
$array = $row;                          
echo "<br />";
echo "<p><font color='#3F7cef'size='5'>$row[32]</font>";       // sets imocode field
if (!function_exists('compare_tons')){
if($sequence='tons') {
function compare_tons($a,$b)
{
return strnatcmp($a['tons'],$a['tons']);
}
uasort($array,"compare_tons");
}
}                                               
print_r($array);                           // enable this line to show all fields in array
    require_once "launch_tableID.php";                 //prints launch table with ID number
    echo launch_tableID();
    echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td><td>$row[5]</td><td>"; 
if($row[6] > 0000-00-00)

...continues to end ?>

I must be completely wrong, can someone point me in right direction, please ?

Member Avatar

diafol

return strnatcmp($a['tons'],$a['tons']);

Is that the line?

As diafol pointed, you're comparing the argument $a on its self and not on $b:

function compare_tons($a,$b)
{
// compares string $a['tons'] from $a['tons']
// OR SHOULD THIS BE $a['tons'] from $b['tons']
return strnatcmp($a['tons'],$a['tons']);
}

Thank you for pointing out the elementary error.
Line 78 now shows: $a['tons'],$b['tons']
After input of $name and radio value='tons'
The display is 190 of this:

( ! ) Notice: Uninitialized string offset: 0 in C:\......php on line 78
Call Stack
#   Time    Memory  Function    Location
1   0.0009  406272  {main}( )   ..\workingjoinIDtest.php:0
2   0.1093  431232  uasort ( )  ..\workingjoinIDtest.php:80
3   0.1093  431488  compare_tons( ) ..\workingjoinIDtest.php:0

followed by the result in proper format but not sorted by field 'tons'

I have amended the code and no warnings/errors now show. But the sorting of the arrays according to the selected radio button using function compare_tons is not working.
Am I taking the wrong approach or misunderstanding the process of sorting ?

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<body>
<form method="post" name="search" action="radiotest2.php"/>
        <font family = "arial,verdana,sans-serif" color="#3F7cef"size="4"/>Enter Ship Name or IMO</font>
        <input type="text"  name="name" size="25" maxlength ="35"/>
        <font family = "arial,verdana,sans-serif" color="#3F7cef"size="4">
        <input type="image" name="submit" src="texts/cooltext591383228.png" onmouseover="this.src='texts/cooltext591383228MouseOver.png';" onmouseout="this.src='texts/cooltext591383228.png';" alt="search"><br/> 
        <p><label><input type="radio" name="sequence" value="alpha" checked="yes">Sort A-Z</label>
        <label><input type="radio" name="sequence" value="tons">Sort by GRT</label>
        <label><input type="radio" name="sequence" value="built">Sort by Year Built</label></p></font>               
</form>
<div class="printarea"/>         <!--line 14 -->              
<?php 
error_reporting (E_ALL ^ E_NOTICE);                                 
if (isset($_POST['name'])) $name = ($_POST ['name']);
else $name = "no name entered";
if (isset($_POST['sequence'])) $sequence=($_POST['sequence']);
$selected_radio = $_POST['sequence'];
//print $selected_radio;
if ($selected_radio == 'alpha'){
$alpha_status= 'checked';
}
if ($selected_radio == 'tons'){
$tons_status= 'checked';
}
if ($selected_radio == 'built'){
$built_status= 'checked';
}                                               
require_once 'dbconnect.php';
  $name = strtoupper($name);
  $name = strip_tags($name);
  $name = trim ($name); 
  $name = mysql_real_escape_string($name);                  
$query = "(SELECT * FROM launch JOIN allnames ON launch.id=allnames.id JOIN fate ON fate.id=allnames.id JOIN imocode ON imocode.id=fate.id WHERE name1 LIKE '$name%' OR name2 LIKE '$name%' OR name3 LIKE '$name%' OR name4 LIKE '$name%' OR name5 LIKE '$name%' OR name6 LIKE '$name%' OR name7 LIKE '$name%' OR name8 LIKE '$name%' OR name9 LIKE '$name%' OR name10 LIKE '$name%' OR name11 LIKE '$name%' OR name12 LIKE '$name%'OR name13 LIKE '$name%' OR name14 LIKE '$name%' OR name15 LIKE '$name%'OR name16 LIKE '$name%' OR name17 LIKE '$name%')UNION(SELECT * FROM launch JOIN allnames ON launch.id=allnames.id JOIN fate ON fate.id=allnames.id JOIN imocode ON imocode.id=fate.id WHERE code LIKE '%$name%')";
$result = mysql_query($query);
if (!$result) die ("Database access failed: " . mysql_error());
$rows=mysql_num_rows($result);
echo "<font color='#3F7cef'size='4'/>You searched for:</font>";
echo "<p>";                              //<br /> justifies left and leaves no spaces  line 41
echo "<font color='#3F7cef'size='6'>";
require_once "fix_it.php";                      // works equally with name and code input
echo fix_it($name); 
echo "</font>";
if (mysql_num_rows($result)== 0){                   //line 
echo "<p><font color='red'size='6px'>No data found for your request. Try a different query</font>";
}
$array=array();                             //absence of this line gives warning:uasort() expects parameter 1
while($row = mysql_fetch_array($result)){               //assoc only displays [keys]
$array = $row;                              //$array[] increments array to each ID
echo "<p><font color='#3F7cef'size='5'>$row[32]</font>";                // sets imocode field;                                                     
print_r($array);                                // or echo
}                                                       
if(!function_exists(compare_tons)){
if ($tons_status='checked'){
function compare_tons($a,$b)
{
return strnatcmp($a['tons'],$b['tons']);
}
uasort($array,'compare_tons');                                     // line 61
}
}

?>
    </body>
    </html>

Hoping somebody can explain sorting of arrays by field or direct me towards a new approach.

Member Avatar

diafol

Why don't you just sort in the sql query with an ORDER BY clause? Make the clause dynamic with a php variable, e.g.

switch($_POST['sequence']){
    case 'az': 
        $sort = 'field1, field2, field3';
        break;
    case 'date': 
        $sort = 'field4 DESC';
        break;
    case 'quantity':
        $sort = 'field17';
        break;
    default:
        $sort = 'field1';
}

$sql = "SELECT field1, field2, field3, field4, field17 FROM table1 ORDER BY $sort";
Member Avatar

diafol

Another idea struck me. You've got helluva query there. I'm no expert, but you may find creating indexes on search fields and then doing fulltext matches in boolean mode useful:

$sql = "SELECT field1, field2, field3, field4 FROM table1 WHERE MATCH (`field2`, `field3`) AGAINST ('{$name}*' IN BOOLEAN MODE)";

Type of thing - gets rid of all the 'OR's
Creating fulltext indexes can be a bit of a chore though.