0

I've a unlimited menu class based on php and mysql that found on stackoverflow. I've customized it for multilanguage web page. But when i'm trying to import a global variable into class, itgives me a warning;

Warning: Invalid argument supplied for foreach() in C:\wamp\www\path\menu.php on line 75

This is Sql query and get_menu_items function:

function get_menu_items()
        {
                global $lang;
                global $visibility;
                $sql = 'SELECT menu. * , menu_lang. * 
                FROM menu
                INNER JOIN menu_lang 
                ON menu.id = menu_lang.menu_id
                AND menu_lang.menu_lang_iso = '.$lang.'
                AND menu_lang.visibility = '.$visibility.'';
                return $this->fetch_assoc_all( $sql );
        }

And $lang variable coming from lang.php file. It looks like;

<?php
ob_start();
session_start();
header('Cache-control: private');
if(isset($_GET["lang"])) {
    $lang = $_GET["lang"];
    $_SESSION["lang"] = $lang;
    setcookie("lang", $lang, time() + (3600 * 24 * 30));
}
elseif(isset($_SESSION["lang"])) {
    $lang = $_SESSION["lang"];
}
elseif(isset($_COOKIE["lang"])) {
    $lang = $_COOKIE["lang"];
}
else {
    $lang = "tr";
    $_SESSION["lang"] = $lang;
    setcookie("lang", $lang, time() + (3600 * 24 * 30));
}
ob_end_flush();

i signed warning line 75 TH LINE, you can find it below;

function get_menu_html( $root_id = 0 )
        {
                $this->html  = array();
                $this->items = $this->get_menu_items();

                foreach ( $this->items as $item )
                        $children[$item['parent_id']][] = $item; // 75. LINE HERE

                $loop = !empty( $children[$root_id] );
....

If i change sql query without variables manuel values it works perfectly;

$sql = 'SELECT menu. * , menu_lang. * 
        FROM menu
        INNER JOIN menu_lang 
        ON menu.id = menu_lang.menu_id
        AND menu_lang.menu_lang_iso = "tr"
        AND menu_lang.visibility = '.$visibility.'';

What am i missing? Does my language script cant handle last else statement, or my get_menu_items function cant import $lang variable?

Any help will greatly appricated.

NoobEditor
  • 15,563
  • 19
  • 81
  • 112
HddnTHA
  • 1,041
  • 3
  • 19
  • 38
  • 3
    If you look at the generated SQL statement from the failing, and compare to the working, you'll seel that you're not quoting the `$lang` variable – Rowland Shaw Sep 15 '14 at 11:24
  • Perhaps this is a good time to start learning about bind variables with MySQLi or PDO – Mark Baker Sep 15 '14 at 11:26
  • @RowlandShaw thx for comment. but i'm using quotes on `$lang` variable --> `else { $lang = "tr"; // HERE $_SESSION["lang"] = $lang; setcookie("lang", $lang, time() + (3600 * 24 * 30)); }` – HddnTHA Sep 15 '14 at 11:26
  • Downvoter make sense and tell me why you downvoted? My question is quiet clear. – HddnTHA Sep 15 '14 at 11:32
  • 1
    @MarkBaker do i need to `bind` all sql queries even doesnt contains any `$_GET`values? – HddnTHA Sep 15 '14 at 11:37
  • 3
    No you don't, but you should..... not only is it a good habit to get into, bind vars will be automatically escaped and quoted for you; they're actually easier to use than injected vars (as your problem here demonstrates), as well as being safer – Mark Baker Sep 15 '14 at 11:39

1 Answers1

2

old school error of string concatenation of quotes '

  $sql = "SELECT menu. * , menu_lang. * 
          FROM menu
          INNER JOIN menu_lang 
          ON menu.id = menu_lang.menu_id
          AND menu_lang.menu_lang_iso = '".$lang."'
          AND menu_lang.visibility = '".$visibility."'";

what it does

this particular section : '".$lang."' will make sure that variable being fetched in query, is quoted with ' quotes around it!

Also, upgrade to better and secure way of doing things

Community
  • 1
  • 1
NoobEditor
  • 15,563
  • 19
  • 81
  • 112