3

I have a problem with the following code.

index.php

$table  = 'test';
$data = [
    'gerecht' => 'Spaghettie',
    'omschrijving' => 'Spaghettie van het huis!'
];
$id = '3';
$crud->updateData($table,$data,$id);

crud.class.php

    public function updateData($table,$data,$id){
    //Query opbouwen
    $query = "UPDATE {$table} SET "; 

    $last_key = end(array_keys($data));
    foreach($data as $key => $value)
    {
        $query .= $key ."=:". $key;
        if ($key == $last_key) {
            $query .= " ";
        } else {
            $query .= ", ";
        }
    }

    $query .= "WHERE id=:id";
    //Query opgebouwd

    $stmt = $this->db->prepare($query);

    foreach($data as $key => $value){
        $stmt->bindparam(":". $key,$value);
    }

    $stmt->bindparam(":id",$id);
    $stmt->execute();

    if($stmt->rowCount()){
        return true; 
    } 
return false;
}

The code "works" but it doesnt do it the right way. It does update at the requested id in the correct table, but the values are both the same.

The data base contains 2 cols (gerecht and omschrijving) and the values that will be updated to the database a both the values "omschrijving"

So whatever i put in gerecht wil be overwriten bij the value omschrijving .

Is there also maybe a more simple way for this code to work ?

Best regards Jocem

8
  • I tested it with the dollowing code <?php $data = [ 'gerecht' => 'Spaghettie', 'omschrijving' => 'Spaghettie van het huis!' ]; $table = "test"; $id = "3"; //////////////////////////////////// $query = "UPDATE {$table} SET "; $last_key = end(array_keys($data)); foreach($data as $key => $value) { $query .= $key ."=:". $key; if ($key == $last_key) { $query .= " "; } else { $query .= ", "; } } $query .= "WHERE id=:id </br>"; //Query opgebouwd foreach($data as $key => $value){ print "stmt->bindparam(:$key,$value)</br>"; } ?> Commented Nov 20, 2015 at 15:19
  • you have $query .= "$key = :$key"; Commented Nov 20, 2015 at 15:22
  • 1
    just print your $query after build and take a look to it Commented Nov 20, 2015 at 15:24
  • Correct cause the query should be ' UPDATE test SET gerecht=:gerecht, omschrijving=:omschrijving WHERE id=:id ' Commented Nov 20, 2015 at 15:25
  • I once has used this method to dynamically to set up query, but I found it is too restrict and lack of flexibility and go for hard code :( Commented Nov 20, 2015 at 15:27

3 Answers 3

1

Try followed:

  public function updateData($table,$data,$id){
    $set = [];

    foreach($data as $key => $value)
    {
        $set[] = "$key = :$key";
    }
    $set = implode(', ', $set);
    $query = "UPDATE $table SET $set WHERE id=:id";
    //Query opgebouwd

    $stmt = $this->db->prepare($query);

    foreach($data as $key => $value) {
        $stmt->bindparam(":$key", $data[$key]);
    }

    $stmt->bindparam(":id", $id);
    $stmt->execute();

    return (bool) $stmt->rowCount();
  }

I think, that issue can be with $value variable binding, this code binds placeholders to array members.

Sign up to request clarification or add additional context in comments.

1 Comment

Well you sir , are my hero ;) That did the trick indeed! Thanks for the help !
1

When dealing with comma seperated strings i suggest the function implode as this function will take care of not filling , at the end of your array so you don't have to.

http://php.net/manual/en/function.implode.php

Example

$table = 'test';
$data = [
    'gerecht' => 'Spaghettie',
    'omschrijving' => 'Spaghettie van het huis!',
];

$updateString = implode(',', array_map(function ($key){
    return sprintf("%s = :%s", $key, $key);
}, array_keys($data)));

$sqlString = sprintf('UPDATE %s SET %s WHERE id = :id', $table, $updateString);

$stmt = $this->db->prepare($sqlString);

array_map(function ($key) use ($data, $stmt) {
    $stmt->bindparam(sprintf(':%s', $key), $data[$key]);
}, array_keys($data));

...bind id, execute whatever

3 Comments

why you use sprintf for set clause, but not for table?
whoops my bad :) i will change it, ty
now looks ok) Main issue(reuse of loop temp variable) was fixed here too.
0

Here's a slightly smaller version of your code:

public function updateData($table,$data,$id) {

    $query = "UPDATE $table SET "
    . implode( ', ',
      array_map( function($key) { return "$key=?"; }, array_keys( $data ) )
    )
    . " WHERE id=?";

    $stmt = $this->db->prepare($query);
    $stmt->execute( array_merge( array_values( $data ), [$id] ) );

    return $stmt->rowCount() != 0;
}

1 Comment

1) foreach uses a different pointer 2) $last_key = end(array_keys($data)); should throw OP a strict standard notice

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.