StoneyJay StoneyJay - 1 month ago 16
PHP Question

How to avoid PHP "Illegal string offset warning" when comparing an variable that will either be an array or null

I am a beginner learning PHP alongside a course on Lynda.com. In the website being built, the navigation menu is made by querying a database for "subjects" and "pages" and then making a table.

Each of these "subjects" and "pages" are links that send an ID number to $_GET to refresh the page and load the specific content. The problem is either the subject array or the page array will always be null (because only one type of thing can be clicked on at once). This is causing the webpage to always throw an "Illegal string offset warning".

if (isset($_GET['subj'])) {
$sel_subject = get_subject_by_id($_GET['subj']);
$sel_page = "NULL";
}
elseif (isset($_GET['page'])) {
$sel_page = get_page_by_id($_GET['page']);
$sel_subject = "NULL";

}
else {
$sel_subject = "NULL";
$sel_page = "NULL";


This is at the top of the .php, and shows at least one of these variables will be NULL instead of an array.

$subject_set= get_all_subjects();

while ($subject = mysqli_fetch_array($subject_set)) {
echo "<li";
if ($subject['id'] == $sel_subject['id']) {
echo " class =\"selected\"";
}
echo "><a href=\"content.php?subj=" . urlencode($subject['id']) .
"\">
{$subject["menu_name"]}</a></li>";

$page_set = get_pages_for_subject($subject['id']);

echo "<ul class=\"pages\">";

while ($page = mysqli_fetch_array($page_set)) {
echo "<li";
if ($page['id'] == $sel_page['id']) {
echo " class =\"selected\"";
}
echo "><a href=\"content.php?page=" . urlencode($page["id"]) . "\"> {$page["menu"]}</a> </li>";
}
echo "</ul>";
}


This is the part of the code that generates the navigation menu. One of the if statements will always try to get an array value from a variable that is null.

Am I doing something wrong? Is this just an inherently bad way of making a navigation menu for the site? I know the course I am using is old, so perhaps PHP programming has made this method obsolete.

Answer

I am a huge fan of is_empty. I don't care of isset can tell you that it is set as an empty string or null. I want to know if there is data, whether it's a string or an array.

Try replacing your isset calls with ! empty()

if (! empty($_GET['subj'])) {
   //
} elseif (! empty($_GET['page'])) {
   //
} else {
   //
}

Also, be sure that you are not taking input directly from the user. If you know those _GET vars are to be integers, clean them before using them.

$page_id = (integer) $_GET['page'];
if (! empty($page_id) {
   // check it out, they can't send us junk anymore!

If they aren't integers, you will have to have a more discerning method of verifying them before using them. But that is a different question, eh?