-1

A PHP function displays the variables, fetching rows from the database. An if rule catches a GET request and would insert values on the table, but it's not what is happening. Which's the problem with the code below? Thanks.

<a href='index.php?add_cart=$pro_id'>
Add to cart
</a>




//rule
if(isset($_GET['add_cart'])){

    global $conn;
    $ip=getIp();
    $pro_id = $_GET['add_cart'];
    $check_pro = "select * from cart where ip_add='$ip' && p_id='$pro_id'";

    $run_check = mysqli_query($conn,$check_pro);

    if(mysqli_num_rows($run_check)>0){
        $insert_pro = "insert into cart (p_id,ip_add,units,size) values ('$pro_id','$ip','1','NULL')";
        $run_pro = mysqli_query($conn,$insert_pro);
        echo "<script>window.open('index.php','_self')</script>";       
    }
    else{
        $insert_pro = "insert into cart (p_id,ip_add,units,size) values ('$pro_id','$ip','1','NULL')";
        $run_pro = mysqli_query($conn,$insert_pro);

        echo "<script>window.open('index.php','_self')</script>";
    }
}

}

Jay Blanchard
  • 32,731
  • 15
  • 70
  • 112
  • 1
    There is no `&&` operand for WHERE clause in MySql so `ip_add='$ip' && p_id='$pro_id'` should be `ip_add='$ip' AND p_id='$pro_id'` – Jorge Campos Apr 06 '20 at 18:13
  • 3
    And PLEASE, use prepared statements on ALL your queries: https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php – Jorge Campos Apr 06 '20 at 18:15
  • 2
    Mysql is probably throwing an error and you are not doing anything here to catch that or report it. Your code is also wide open for a sql injection attack. [Properly bind your parameters](https://stackoverflow.com/questions/17053466/how-to-display-errors-for-my-mysqli-query) this isn't just good security practice, it will also save you from more errors. Also... don't insert `'Null'` as a string literal. That seems strange. – JNevill Apr 06 '20 at 18:16
  • Thank you so much. I should know. – Ivan Zanoth Apr 06 '20 at 18:17
  • SQL Injection alert! – Mohsen Nemati Apr 06 '20 at 18:17
  • Actually @JorgeCampos `&&` is legal in a MySQL query though it is due to be deprecated in MySQL 8 https://dev.mysql.com/doc/refman/8.0/en/logical-operators.html – Jay Blanchard Apr 06 '20 at 18:19
  • Definitely need to second what jorge and mohsen are saying. Use prepared statements to help avoid one of the most common security vulnerabilities (SQL Injection). – Nibb Apr 06 '20 at 18:23
  • But niente... Is mandatory prepared statements? Ik about security and faults, while i'm on the go in experimental level. Grateful – Ivan Zanoth Apr 06 '20 at 18:29
  • The operator is changed right now, what explain the persistent behavior? – Ivan Zanoth Apr 06 '20 at 18:32
  • @IvanZanoth `Is mandatory prepared statements?` it is not mandatory, though if you start learning and coding the "wrong way" this will probably follow you in your future... – Jorge Campos Apr 06 '20 at 19:10
  • @JayBlanchard Thanks for the info. At least they are making MySQL more SQL Ansi on version 8 – Jorge Campos Apr 06 '20 at 19:11

1 Answers1

0

You can check for the following code in associate to mysqli prepare and binding parameters.

if (isset($_GET['add_cart'])) {

    $conn = new mysqli('server', 'user', 'password', 'database');

    if (mysqli_connect_errno()) {
        echo 'connection failure: '.mysqli_connect_errno(); 
        exit;
    }

    try {
        // ... 

        /* prepare query statement
           check for existence id + ip at first.
         */
        $query = $conn->prepare(
            'insert into cart (id, ip, units, size) '.
            'select * from (select ?, ?, ?, ?) t '.
            'where (select id from cart where id = ? and ip = ? limit 1) is null'
        );

        /* Binding parameters:
           i : integer type
           s : string type
           d : double type  
         */
        $query->bind_param('issdis', $id, $ip, $units, $size, $id, $ip);

        /* execute query statement and close after execution */

        try {
            $query->execute();
            echo 'Row created: '. $query->affected_rows;

            /* when no row created and want to update the existing row */
            /* if ($query->affected_rows === 0) {
                $query->close();

                $query = $conn->prepare(
                    'update cart '.
                    'set unit = ?, size = ? '.
                    'where id = ? and ip = ?'
                );

               $query->bind_param('sdis', $units, $size, $id, $ip);

               $query->execute();
               echo 'Row updated: '. $query->affected_rows;
            } */

        } catch (\Exception $e) {
            echo $e->getMessage();

        } finally {
            $query->close();
        }

    } finally {
        /* make sure to close the database connection */
        $conn->close();
    }
}

//...

And this is safeMySqli class extends from mysqli class.

class safeMySqli extend mysqli {

    protected static $instances = null;

    public static function create($server, $user,  $password, $database) {
        $class = get_called_class();

        if (is_null(static::$instances[$class])) {
            static::$instances = new $class($server, $user, $password, $database);
        }
       return static::$instances;
    }

    /* execute query and return statement.
        arguments:
            - $query = sql query
            - any query parameters
            eg: $db.execute('select * from gen where id = ? and type = ?', 1, 'OO7');
     */

    public function execute($query) {
        $stmt = $this->prepare($query);

        $args = func_get_args();
        $argsLength = count($args);

        if ($argsLength > 1) {
            $params = [''];

            for ($i = 1; $i < $argsLength; $i++) {
                $val = $args[$i];
                $params[0] = $param[0] . (is_int($val) ? 'i' : (is_double($val) ? 'd' : (is_string($val) ? 's' : 'b')));
                $params[] = &$args[$i];
            }

            call_user_func_array([$stmt, 'bind_param'], $params);
        }

        $stmt->execute();

        return $stmt;
    }
}

Usage:

$db = new safeMySqli('server', 'database', 'user', 'password', 'database');
// or...
$db = safeMySqli::create('server', 'database', 'user', 'password', 'database');

// query execution...
$stmt = $db.execute('select * from gen where id = ? and type = ?', 1, 'OO7');

// get query result
$result = $stmt->get_result();
$rows = $result->fetch_all();

// close resources
$result->close();
$stmt->close();
$db->close();

Edit Correction for correct parameter type checking.

OO7
  • 565
  • 2
  • 9