Hi, as you know i'm creating my own CMS.
This is a part of my code:

     if (!empty($_POST["Title"]) && !empty($_POST["Author"]) && !empty($_POST["Content"])) {
         $sql = "INSERT INTO Posts (Title, Author, Content)
         VALUES ('$title', '$author', '$content')";
     }

I want the script to check if Title Field and Author field and Content field are empty, stop sending blank rows into table. Because when i click the submit button while all these fields are empty and then check the table, i see blank rows added into table.

Now with the code above, no blank rows will be added to table but when i click the submit button while all those fields are empty, this error will be appeared on the top of the page suddenly!
General error: trying to execute an empty query
Well, how can i remove that error from the top of the page?!

Depending on how your overall approach is to processing form data, but in general it is as easy as:

if(empty(trim($_POST["Title"])) || empty(trim($_POST["Author"])) || empty(trim($_POST["Content"]))) {
    echo "You forgot to enter some required data";
    // go back to the form
} else {
    // 
    // I HOPE YOU DO SOME FILTERING / SANITIZING HERE 
    // OR USE PREP. STATEMENTS
    // 
    $sql = "INSERT INTO Posts (Title, Author, Content)
    VALUES ('$title', '$author', '$content')";
}

Note that I also used the trim function to get rid of possible spaces which are also of no use in your database fields.

@broj1, i tested your code, the result was almost the same as mine. No blank rows will be added into table and it's good, but that error is still appeared on the top of the page, and now just this sentence "You forgot to enter some required data" is appeared on the top of that error.

OK, then let's do some simple debugging. Insert this line of code just after line 4 in your first snippet:

die($sql);

This will stop the script and display the query that is giving us hard time. Please post the displayed query here.

I add that part after line 4, after }else{.
The result was the same as before. No blank rows has been addded into table but this error appears on the top of the page:

You forgot to enter some required data
SQLSTATE: General error: trying to execute an empty query 

Can you post the rest of the code. The error is comming from some lines after your snippet.

<?php
$servername = "localhost";
$dbname = "mydbname";
$dbusername = "mydbusername";
$dbpassword = "mydbpassword";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $title = $_POST['title'];
    $author = $_POST['author'];
    $content = $_POST['content'];

    if(empty($_POST["title"]) || empty($_POST["author"]) || empty($_POST["content"])) {
        echo "You forgot to enter some required data";
    } else {
        die($sql);
        $sql = "INSERT INTO Posts (Title, Author, Content)
        VALUES ('$title', '$author', '$content')";
    }

    $conn->exec($sql);
    }
catch(PDOException $e)
    {
    echo $sql . "<br>" . $e->getMessage();
    }

$conn = null;
?>


<html>
<head>
<title>Admin Area</title>
</head>
<body>
<h1>Welcome <?php echo $_POST["username"]; ?> To Admin Area</h1>

<h2>Feel free to write your new post:</h2>
<form method="post">
   Title: <input type="text" name="title">
   <br><br>
   Author: <input type="text" name="author">
   <br><br>
   Content: <textarea name="content" rows="10" cols="40"></textarea>
   <br><br>
   <input type="submit" name="submit" value="Submit">
</form>


</body>

This is the PHP part. It is slightly rearanged so the connection and execution gets done only if there are all fields:

<?php
    $title = $_POST['title'];
    $author = $_POST['author'];
    $content = $_POST['content'];

    if(empty($_POST["title"]) || empty($_POST["author"]) || empty($_POST["content"])) {
        echo "You forgot to enter some required data";

    } else {

        // this is just for debugging
        // die($sql);

        $servername = "localhost";
        $dbname = "mydbname";
        $dbusername = "mydbusername";
        $dbpassword = "mydbpassword";

        try {
            $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $sql = "INSERT INTO Posts (Title, Author, Content)
                VALUES ('$title', '$author', '$content')";

            $conn->exec($sql);
        } catch(PDOException $e) {
            echo $sql . "<br>" . $e->getMessage();
        }

        $conn = null;
    }
?>

And for security reasons use prepared statements.

What do you mean by this? Sorry my English is not good enough, so i didn't understand what you mean by this:

And for security reasons use prepared statements.

Yes it works. Now when i click the submit button, no blank rows will be added into table and no error appears on the top of the page. Thank you.

But there is an other problem now.
First i login to this page(the page of writting posts) from login.php page by entering username and password, but suddenly after entering to the page of writting posts, the message "You forgot to enter some required data" will appear on the top of the page, but i haven't clicked submit button yet!
How can i fix it? I don't want script to show this message exactly after login to page without any action.

And for security reasons use prepared statements.

Prepared statements are a feature of a database (like mysql). Variables that are passed to a query get prepared first so a possibility of an injection of bad code is minimized. This is a preferrable way of inserting user supplied data into the database. Your code will look something like:

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = "INSERT INTO Posts (Title, Author, Content)
    VALUES (:title, :author, :content)";
    $stmt->bindParam(':Title', $title);
    $stmt->bindParam(':Author', $author);
    $stmt->bindParam(':Content', $content);
    $conn->exec($sql);
} catch(PDOException $e) {
    echo $sql . "<br>" . $e->getMessage();
}

As you can see in the query there are placeholders for variables and actual values are them bound to those placeholders. Also see this article.

To execute the code only after form submission the whole thing has to be wrapped in an if block:

<?php
if(isset($_POST['submit'])) {

    $title = $_POST['title'];
    $author = $_POST['author'];
    $content = $_POST['content'];

    if(empty(trim($_POST["title"])) || empty(trim($_POST["author"])) || empty(trim($_POST["content"]))) {
            echo "You forgot to enter some required data";
    } else {

        $servername = "localhost";
        $dbname = "mydbname";
        $dbusername = "mydbusername";
        $dbpassword = "mydbpassword";

        try {
            $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $sql = "INSERT INTO Posts (Title, Author, Content)
            VALUES (:title, :author, :content)";
            $stmt->bindParam(':Title', $title);
            $stmt->bindParam(':Author', $author);
            $stmt->bindParam(':Content', $content);
            $conn->exec($sql);
        } catch(PDOException $e) {
            echo $sql . "<br>" . $e->getMessage();
        }
        $conn = null;
    }
}
?>

I rearranged your code to include changes from my previous posts.

THank you @broj1, it works. But i had to change this:

if(empty(trim($_POST["title"])) || empty(trim($_POST["author"])) || empty(trim($_POST["content"]))) {

to this:

if(empty($_POST["title"]) || empty($_POST["author"]) || empty($_POST["content"])) {

Because with using trim() i got error.

I read the link you gave me, but could you please explain every line i will point to? I can't understand them wellm need some more clear explanation, thank you.

$sql = "INSERT INTO Posts (Title, Author, Content)

//why you have used : sign before each one? what does it do?
VALUES (:title, :author, :content)";

// what is $stmt for?
// what does bindParam do exactly?
$stmt->bindParam(':Title', $title);
$stmt->bindParam(':Author', $author);
$stmt->bindParam(':Content', $content);
$conn->exec($sql);
} catch(PDOException $e) {

// why you have typed echo $sql in this line?
//what does it echo and print on the page?
//(sql is the variable here that holds an order, the order of inserting data into table, right?
//so the $sql variable has not anything to echo and print, right?
//maybe is misunderstanding for me.
echo $sql . "<br>" . $e->getMessage();

First I have to admit there are errors in my code. e.g. I forgot to copy the prepare statement which is most important here. So the right code is (see explanations in comments):

$servername = "localhost";
$dbname = "mydbname";
$dbusername = "mydbusername";
$dbpassword = "mydbpassword";

try {
    // You initialize the connection here using OOP style
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);

    // here you say that you will use exception mode for 
    // error handling this is basically the try/catch block
    $conn->setAttribute(PDO::ATTlR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // the SQL statement uses placeholders for values
    // that will be replaced with values of variabes;
    // the colon (:) is denoting the placeholders
    $sql = "INSERT INTO Posts (Title, Author, Content)
        VALUES (:title, :author, :content)";

    // prepare a statement (that is why it is named $stmt)
    $stmt = $conn->prepare($sql);

    // bind real values to placeholders
    // e.g. placeholder named :title receives a value of $title etc
    $stmt->bindParam(':title', $title);
    $stmt->bindParam(':author', $author);
    $stmt->bindParam(':content', $content);

    // now execute the prepared statement
    $conn->exec($sql);

// if exception happens (basically if error occurs) handle it
} catch(PDOException $e) {
    echo $sql . "<br>" . $e->getMessage();
}

// unset the connection (to free resources)
$conn = null;

You also have a very nice and complete tutorial here.

It is strange that you get an error trimming the user input. It is quite important to do it since users sometimes add spaces on beginning or end without knowing and noticing it. Maybe you should change that line of code to:

if(trim($_POST["title"]) == '' || trim($_POST["author"]) == '' || trim($_POST["content"]) == '') {
...

What error do you actually get?

This is that error:

PHP Fatal error:  Can't use function return value in write context in Line 8

And this is line 8:

if(empty(trim($_POST["title"])) || empty(trim($_POST["author"])) || empty(trim($_POST["content"]))) {

Thank you @broj1 for clear explanation and for the link.

So now i just should add this line $stmt = $conn->prepare($sql); before line 24 $stmt->bindParam(':Title', $title); correct? i did.

OK, seems this error is since empty can not be used this way. You can use the if block that I posted in my previous post if you wish (recommended).

And yes, you should add the prepare line before binding. Hopefuly all will work OK. Anyway, if you get errors post them here.

I understood.
But there is one more problem.
There are 3 fields in the form to be filled: title and author and content.
If i leave all 3 fields empty, or just fill one or two of them and click the submit button, the message "You forgot to enter some required data" appears and no blank row will be added into db.
But if i fill all 3 fields and click the submit button, nothing will be sent to db and this error will be appeared on the top of the page:

INSERT INTO Posts (Title, Author, Content) VALUES (:title, :author, :content)
 Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':title, :author, :content)' at line 2 

There are still some errors that somehow sneaked into my code :-). This is what happens when there is no time to test. These are the errors:

// wrong
$conn->setAttribute(PDO::ATTlR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// correct
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// wrong
$conn->exec($sql);
// correct
$stmt->execute();

So this part of code should be (tested, and it works):

$servername = "localhost";
$dbname = "test";
$dbusername = "test";
$dbpassword = "";

try {
    // You initialize the connection here using OOP style
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $dbusername, $dbpassword);
    // here you say that you will use exception mode for
    // error handling this is basically the try/catch block
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    // the SQL statement uses placeholders for values
    // that will be replaced with values of variabes;
    // the colon (:) is denoting the placeholders
    $sql = "INSERT INTO Posts (Title, Author, Content)
            VALUES (:title, :author, :content)";
    // prepare a statement (that is why it is named $stmt)
    $stmt = $conn->prepare($sql);
    // bind real values to placeholders
    // e.g. placeholder named :title receives a value of $title etc
    $stmt->bindParam(':title', $title, PDO::PARAM_STR);
    $stmt->bindParam(':author', $author, PDO::PARAM_STR);
    $stmt->bindParam(':content', $content, PDO::PARAM_STR);
    // now execute the prepared statement
    $stmt->execute();
    // if exception happens (basically if error occurs) handle it
} catch(PDOException $e) {
    echo $sql . "<br>" . $e->getMessage();
}

Sory for the errors in my posts. Speed does not always help.

Yes it works well with no error now.

Sory for the errors in my posts. Speed does not always help.

No need to be sorry, it's ok. Errors are a part of coding. Thank you again for your help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.