-1

My SQL Statement works in phpMyAdmin, but when I use PHP to run it from my webpage, it does nothing.

My code is as below, which always returns true. I have solved this problem, but the primary problem is that the code does not delete the row.

// Delete Area
public function deleteArea($product_area_id){
    $this->db->query("
    DELETE 
    FROM product_area 
    WHERE product_area_id = :product_area_id 
    LIMIT 1
    ");
    //bind
    $this->db->bind(':product_area_id', $product_area_id);
    //Execute
    if($this->db->execute()){
        return true;
    } else {
        return false;
    }
}

My database class:

public function bind($param, $value, $type = null) {
    if (is_null ( $type )) {
        switch (true) {
            case is_int ( $value ) :
                $type = PDO::PARAM_INT;
                break;
            case is_bool ( $value ) :
                $type = PDO::PARAM_BOOL;
                break;
            case is_null ( $value ) :
                $type = PDO::PARAM_NULL;
                break;
            default :
                $type = PDO::PARAM_STR;
        }
    }
    $this->stmt->bindValue ( $param, $value, $type );
}

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

public function execute(){
    return $this->stmt->execute();
}
Warren Sergent
  • 2,542
  • 4
  • 36
  • 42
codenoob
  • 539
  • 1
  • 9
  • 26

3 Answers3

1

You're mixing PDO with the mysql_ functions. They do NOT work interoperably. What you need here is rowCount

$this->db->query("
    DELETE 
    FROM product_area 
    WHERE product_area_id = :product_area_id 
    LIMIT 1
    ");
    //bind
    $this->db->bind(':product_area_id', $product_area_id);
    //Execute
    $this->db->execute();
    if(this->db->rowCount() > 0){
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • Hi Machavity, Now it is correctly realizing the delete did not work, but why is the delete statment not working. Since if I paste the SQL into phpmyadmin change :product_area_id to a number. it will delete the row. – codenoob Jun 27 '16 at 19:37
  • Shouldn't it be `$this->statement->rowCount()`? There is no `PDO::rowCount()` method. – Barmar Jun 27 '16 at 19:40
  • sorry for the confusion. the db is a variable I added. so $this->db->rowCount() is the same as $this->stmt->rowCount(); – codenoob Jun 27 '16 at 19:43
0

A comment quote from the op (the last comment at the moment):

The primary problem is, it will not delete. even though the sql statment is correct when tested directly in phpmyadmin. the secondary problem is, it will also say true. even though it didn't delete. Machavity solved the secondary problem. the primary remains. - codenoob

TLDR: // Note: PDOStatement::execute .... Returns TRUE on success or FALSE on failure.

So that is why it returns 1 all the time for you. See the below for 2 files to test this with a change using rowCount() off of a PDOStatement object.

You said in comments that the primary problem remains. I have no problem using the below after sort of hand crafting a database class, because you did not offer one (you mention one). Note the use of try/catch blocks.

Frankly we don't know if you had any exceptions or how you are handling them, or whether or not you have error reporting activated. The below should survive any testing, assuming the pdo object can successfully return the rowCount() value.

Schema for testing:

create table product_area
(   product_area_id int primary key,
    theName varchar(100) not null
);
--  blockA begin
truncate product_area;
insert product_area (product_area_id,theName) values
(1,'Houston zone B'),(2,'Houston zone BH'),(20,'Houston zone Z');
--  blockA end

Test File:

For the test file, there are only a few lines of code near the top for testing in the section called "Mini test area"

<?php
//  pdo_del_test_20160703.php
// related to answering http://stackoverflow.com/questions/38061597 at the moment

error_reporting(E_ALL);
ini_set("display_errors", 1);
include "myPDO_DB.php"; // Database class. The class name = myPDO_DB

// Mini test area BEGIN:
$a1=new aClass();
$ret=$a1->deleteArea(2);
echo "retValue=".$ret."<br>";
// Mini test area ... END

class aClass {
    private $db=null;

    public function __construct(){
        echo "in constructor1<br>";
        $this->db=new myPDO_DB();
        echo "in constructor2<br>";
        //$this->db=null;
        echo "in constructor3<br>";
    }

    public function deleteArea($product_area_id){
        $this->db->query("
        DELETE  
        FROM product_area 
        WHERE product_area_id = :product_area_id  
        LIMIT 1
        ");
        // Note: PDOStatement::execute .... Returns TRUE on success or FALSE on failure.
        //
        // so on a Delete call, it just says sure, OK, done with that (if no exception)
        // It doesn't give feedback natively as to whether or not a row was actually deleted
        //
        //bind
        $this->db->bind(':product_area_id', $product_area_id);
        //Execute

        // Don't forget to run schema `blockA` before testing (so that data is there)
        if ($this->db->execute()) { // if this function returns anything other than TRUE you have exception problems
            $pdo_rowcount=$this->db->stmt->rowCount();  // see http://php.net/manual/en/pdostatement.rowcount.php

            // Depending on your systems ability to get pdo.rowCount() to work, consider the following

            // Please see http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_row-count
            $this->db->query("select row_count()"); // from mysql "Information Functions". Based on prior mysql call.
            $mysql_rowcount=$this->db->execute();

            // but note, row_count() in mysql is not exactly a solution for the majority of systems out there.
            // http://www.heidisql.com/forum.php?t=9791
            // on mysql 5.5 and my 5.6.24, it returns 0

            // so depending on your system, you will choose between $pdo_rowcount and $mysql_rowcount
            return $pdo_rowcount;   // your best bet, bust test it on your setup.
        }
        else {
            // do something
            return 0; // you would have already endured an exception though
        }
    }
}
?>

Database class:

<?php
//  myPDO_DB.php
//
error_reporting(E_ALL);
ini_set("display_errors", 1);
include "db_connect_info.php";  // brings in the "defines" .. Shoot for a secure o/s vault in this file.

class myPDO_DB { 
    // will grab the stub from http://culttt.com/2012/10/01/roll-your-own-pdo-php-class/
    //
    // and then build your class into it (because you did not provide it)
    //
    // and then further improve it with try/catch blocks that were lacking
    //

    private $host      = DB_HOST; // these were brought in with the include above. File not shown.
    private $user      = DB_USER;
    private $pass      = DB_PASS;
    private $dbname    = DB_NAME;

    private $dbh;
    public $stmt;   // was made public to get into rowCount(); .... change this for your needs
    private $error;

    public function __construct(){
        // Set DSN
        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
        // Set options
        $options = array(
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_EMULATE_PREPARES => false
        );

        // Create a new PDO instanace
        try{
            $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
            echo "Connect Ok<br>";
        }
        catch(PDOException $e){
            $this->error = $e->getMessage();
        }
    }

    public function bind($param, $value, $type = null) {
        try {
            if (is_null ( $type )) {
                switch (true) {
                    case is_int ( $value ) :
                    $type = PDO::PARAM_INT;
                    break;
                case is_bool ( $value ) :
                    $type = PDO::PARAM_BOOL;
                    break;
                case is_null ( $value ) :
                    $type = PDO::PARAM_NULL;
                    break;
                default :
                    $type = PDO::PARAM_STR;
                }
            }
            $this->stmt->bindValue ( $param, $value, $type );
        }
        catch(PDOException $e){
            $this->error = $e->getMessage();
            throw $e;
        }
    }

    public function query($query) {
        try {
            $this->stmt = $this->dbh->prepare($query);
        }
        catch(PDOException $e){
            $this->error = $e->getMessage();
            throw $e;
        }
    }

    public function execute(){
        try {
            return $this->stmt->execute();
        }
        catch(PDOException $e){
            $this->error = $e->getMessage();
            throw $e;
        }
    }
} 
Drew
  • 24,851
  • 10
  • 43
  • 78
  • Also note that if your id that you are deleting is a primary key (I just stubbed something to together), then your `LIMIT 1` is not needed. – Drew Jul 03 '16 at 21:37
-1

Sorry I derped. the value I passed in was $Product_area_id and the one I used is $product_area_id. god.

codenoob
  • 539
  • 1
  • 9
  • 26