Avatar of B O
B O
 asked on

I am busy creating a edit function that dynamically get seleted files and creates a dynamic query based on the selected files and text input, I almost have it but have an error Invalid parameter numbr

I am busy creating a edit function that dynamically get seleted files and
creates a dynamic query based on the selected files and text input,

I thnk I almost have it working correctly but I have an error Invalid parameter number:
number of bound variables does not match number of tokens in C:\xampp\htdocs\shareposts\app\libraries\Database.php:56

I am now looking at my model and controller, how to get it working

I think the problem is where I try to dynamically add the new data to the right columns
inside the $data array/object

Controller
// edit post
    public function edit($id){
      if($_SERVER['REQUEST_METHOD'] == 'POST'){
....
$data = [
                'id' => $id,
                'title' => trim($_POST['title']),
                'type_work' => $_POST['type_work'],
                'body' => trim($_POST['body']),
                'user_id' => $_SESSION['user_id'],
                'title_err' => '',
                'body_err' => ''
            ];


foreach($img['name'] as $index => $filename) {  
                    // echo "<b>Name</b>: {$img['name'][$index]}<br>";
                    // echo "<b>Type</b>: {$img['type'][$index]}<br>";
                    // echo "<b>Temp Name</b>: {$img['tmp_name'][$index]}<br><br>";


                    $fileExtension = explode(".", $img['name'][$index]);
                    $fileActualName = strtolower(array_shift($fileExtension));
                    $fileActualExt = strtolower(end($fileExtension));
                    $allowed = array("jpg", "jpeg", "png");
    
                    // set new name for image
                    $imageFullName = $fileActualName . "." . uniqid("", true) . "." . $fileActualExt;
                    // set destination of image
                    $fileDestination = dirname(__DIR__, 2). '/public/img/posts/' . $imageFullName;


                    // get all columns names
                    $database->query('SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA="shareposts" AND TABLE_NAME="posts"');
                    
                    // variable contains the results of query
                    $results[0] = $database->resultSet();


                    // dynamic name resembles column names
                    $name = 'img_' . $index;
                    
                    // names of columns in array
                    $namesColumns = array($results[0][0]->{'GROUP_CONCAT(COLUMN_NAME)'});


                    // if database dynamic name matches array of columnNames inside database
                    if(in_array($name, explode(',',$namesColumns[0]))){


                        // look if there is data in column
                        if(!empty($post->$name)){
                            // get path to file name of column by id
                            $deleteThisFile = dirname(__DIR__, 2). '/public/img/posts/' . $post->$name;
                            // delete file to make space for new file
                            if(unlink($deleteThisFile)){
                                // load new image to array 
                                array_push($data,['img_'.$index => $imageFullName]);
                                // die('success unlink');
                            } else {
                                die('Unlink not success');
                            }
                        }
                        
                        
                    } else {
                        print_r('couldnt match ' . $name . ' ' . var_dump($sql));
                    }


                    // Move new file
                    if(move_uploaded_file($img['tmp_name'][$index], $fileDestination)){
                        // set data ready for upload to database
                        array_push($data,['img_'.$index => $imageFullName]);
                        
                    } else {
                        die('files couldn\'t be moved to destination');
                    }
                }
            }


 // validated
                if($this->postModel->updatePost($data)){
                    flash('post_message', 'Post Added');
                    redirect('posts');
                } else {
                    die('Something went wrong');
                }
                die('success end edit function');


            }
}

Open in new window



Model
        public function updatePost($data){
            $this->db->query('UPDATE posts set title = :title, body = :body, img_0 = :img_0,                img_2 = :img_2, img_3 = :img_3, img_4 = :img_4 WHERE id = :id');
            
                //  Bind Values
                $this->db->bind(':id', $data['id']);
                $this->db->bind(':title', $data['title']);
                $this->db->bind(':type_work', $data['type_work']);                
                $this->db->bind(':body', $data['body']);


                // get data row by id
                $post = $this->getPostById($data['id']);


                $this->db->bind(':img_0', (isset($data[0]['img_0']))? $data[0]['img_0']: $post->img_0);
                $this->db->bind(':img_1', (isset($data[1]['img_1']))? $data[1]['img_1']: $post->img_1);
                $this->db->bind(':img_2', (isset($data[2]['img_2']))? $data[2]['img_2']: $post->img_2);
                $this->db->bind(':img_3', (isset($data[3]['img_3']))? $data[3]['img_3']: $post->img_3);
                $this->db->bind(':img_4', (isset($data[4]['img_4']))? $data[4]['img_4']: $post->img_4);
    
                // Execute
                if($this->db->execute()){
                    return true;
                } else {
                    return false;
                }
        }

Open in new window


View
<form action="<?php echo URLROOT; ?>/posts/edit/<?php echo $data['id']; ?>" method="post" enctype="multipart/form-data">
                
                <div class="form-group">
                    <label for="title">Title: <sup>*</sup></label>
                    <input type="title" name="title" class="form-control form-control-lg <?php echo (!empty($data['title_err'])) ? 'is-invalid' : ''; ?>" value="<?php echo $data['title']; ?>" >
                    <span class="invalid-feedback"><?php echo $data['title_err']; ?></span>
                </div>


                <div class="form-group">
                    <label for="type_work">Short description of type work: <sup>*</sup></label>
                    <input type="title" name="type_work" class="form-control form-control-lg" value="<?php echo isset($data['type_work']) ? $data['type_work'] : ''; ?>" >
                    <span class="invalid-feedback"></span>
                </div>
                
                <div class="form-group">
                    <label for="body">Text: <sup>*</sup></label>
                    <textarea name="body" class="form-control form-control-lg <?php echo (!empty($data['body_err'])) ? 'is-invalid' : ''; ?>"><?php echo $data['body']; ?></textarea>
                    <span class="invalid-feedback"><?php echo $data['body_err']; ?></span>
                </div>


                 <!-- Images upload -->
                 <div class="form-group">
                    <label for="img">Image<sup>1</sup>: Main Image</label>
                    <input type="file" name="img[]" class="form-control form-control-lg<?php echo (!empty($data['img_err'])) ? 'is-invalid' : ''; ?>"  multiple>
                    <span class="invalid-feedback"><?php echo $data['img_err']; ?></span>
                </div>


                <input type="submit" class="btn btn-success" value="Submit">
              
            </form>

Open in new window



database: line 55 -57
// execute the prepared statement
    public function execute(){
 ->line 56   return $this->stmt->execute();
    }





Error

when I refresh

When I look in the database table: I see no Changes at all


Files has been moved to folder correctly

DatabasesPHP

Avatar of undefined
Last Comment
B O

8/22/2022 - Mon
Chris Stanyon

Hey there,

If you look at your Model, you have 7 placeholders in your Query, but you're trying to bind 9 values:

// 7 PlaceHolders !!
$this->db->query('UPDATE posts set title = :title, body = :body, img_0 = :img_0, img_2 = :img_2, img_3 = :img_3, img_4 = :img_4 WHERE id = :id');
            
// 9 Bindings !!
$this->db->bind(':id', $data['id']);
$this->db->bind(':title', $data['title']);
$this->db->bind(':type_work', $data['type_work']);                
$this->db->bind(':body', $data['body']);
$this->db->bind(':img_0', (isset($data[0]['img_0']))? $data[0]['img_0']: $post->img_0);
$this->db->bind(':img_1', (isset($data[1]['img_1']))? $data[1]['img_1']: $post->img_1);
$this->db->bind(':img_2', (isset($data[2]['img_2']))? $data[2]['img_2']: $post->img_2);
$this->db->bind(':img_3', (isset($data[3]['img_3']))? $data[3]['img_3']: $post->img_3);
$this->db->bind(':img_4', (isset($data[4]['img_4']))? $data[4]['img_4']: $post->img_4);

Open in new window

It looks like you might also be manipulating your $data array incorrectly, but the error you're getting is down to the mismatch between placeholders and parameters
B O

ASKER
Thank you for replying

I edit the code

But nothingchanged

I got the same error
 $this->db->query('UPDATE posts set title = :title, type_work = :type_work, body = :body, img_0 = :img_0, img_1 = :img_1, img_2 = :img_2, img_3 = :img_3, img_4 = :img_4 WHERE id = :id');
            
                //  Bind Values
                $this->db->bind(':id', $data['id']);
                $this->db->bind(':title', $data['title']);
                $this->db->bind(':type_work', $data['type_work']);                
                $this->db->bind(':body', $data['body']);


                // get data row by id
                $post = $this->getPostById($data['id']);


                $this->db->bind(':img_0', (isset($data[0]['img_0']))? $data[0]['img_0']: $post->img_0);
                $this->db->bind(':img_1', (isset($data[1]['img_1']))? $data[1]['img_1']: $post->img_1);
                $this->db->bind(':img_2', (isset($data[2]['img_2']))? $data[2]['img_2']: $post->img_2);
                $this->db->bind(':img_3', (isset($data[3]['img_3']))? $data[3]['img_3']: $post->img_3);
                $this->db->bind(':img_4', (isset($data[4]['img_4']))? $data[4]['img_4']: $post->img_4);
    

Open in new window



B O

ASKER
I see the issue when I var_dump the $data

In my foreach only the fitrst selected element of my $_FILES get pushed to the $data array
How do I correct it and get all new data pushed to the $data array

foreach($img['name'] as $index => $filename) {  
                    // echo "<b>Name</b>: {$img['name'][$index]}<br>";
                    // echo "<b>Type</b>: {$img['type'][$index]}<br>";
                    // echo "<b>Temp Name</b>: {$img['tmp_name'][$index]}<br><br>";


                    $fileExtension = explode(".", $img['name'][$index]);
                    $fileActualName = strtolower(array_shift($fileExtension));
                    $fileActualExt = strtolower(end($fileExtension));
                    $allowed = array("jpg", "jpeg", "png");
    
                    // set new name for image
                    $imageFullName = $fileActualName . "." . uniqid("", true) . "." . $fileActualExt;
                    // set destination of image
                    $fileDestination = dirname(__DIR__, 2). '/public/img/posts/' . $imageFullName;


                    // get all columns names
                    $database->query('SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA="shareposts" AND TABLE_NAME="posts"');
                    
                    // variable contains the results of query
                    $results[0] = $database->resultSet();


                    // dynamic name resembles column names
                    $name = 'img_' . $index;
                    
                    // names of columns in array
                    $namesColumns = array($results[0][0]->{'GROUP_CONCAT(COLUMN_NAME)'});


                    // if database dynamic name matches array of columnNames inside database
                    if(in_array($name, explode(',',$namesColumns[0]))){


                        // look if there is data in column
                        if(!empty($post->$name)){
                            // get path to file name of column by id
                            $deleteThisFile = dirname(__DIR__, 2). '/public/img/posts/' . $post->$name;
                            // delete file to make space for new file


                            // if(unlink($deleteThisFile)){
                            if($deleteThisFile){
                                // load new image to array 
                                array_push($data,['img_'.$index => $imageFullName]);
                                // die('success unlink');
                            }
...
}

Open in new window


Only the first selected image get pushed to the $data object/array