phphtmlfopenfwrite

Create an entirely new html page with specified name fetched from form and add specific contents to it using PHP


I would like my page to allow me to fill up a form and then press submit button that initiates another PHP file that firstly inserts the data into the database, and secondly creates an entirely new page using the given pageName fetched from the form and adds specified contents to it using PHP.

My codes are : The database connection:

<?php
    
    $servername = 'localhost';
    $username = 'root';
    $password = '';
    $dbname = 'hm';
    // Create connection
    $conn = mysqli_connect($servername, $username, $password , $dbname);

    // Check connection
    if (!$conn) {
        die("Connection failed: " . mysqli_connect_error());
      }      
    echo "Connected successfully";

?>

The form:

<form action="add_recipe_script.php" method="post" enctype=”multipart/form-data”  >
   
    <label>Page Name <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="pageName"  placeholder="Page name" required>
    </div><br/>
    <label>Recipe Name <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rName"  placeholder="Recipe name" required>
    </div><br/>
    
    <label>Recipe Discription:<span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rDisc" placeholder="Recipe Description" required>
    </div><br/>

    <label>Recipe Image:<span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rImg" placeholder="Recipe Image" required>
    </div><br/>
    
    <label >Recipe Category: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rCategory"  placeholder="Recipe Category" required>
    </div><br/>

    <label>No. of Calories: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rTotalCalories"  placeholder="Recipe Calorie" required>
    </div><br/>

    <label>No. of Servings: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rServing"  placeholder="Recipe Servings" required>
    </div><br/>

    <label>Cook time: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rTime"  placeholder="Cook time" required>
    </div><br/>

    <label>Recipe Ingredients: <span style="color: #FF0000">*</span></label>
    <div>
        <textarea name="rIngre"  placeholder="Recipe Ingredients" required></textarea>
    </div><br/>

    <label>Recipe Instructions: <span style="color: #FF0000">*</span></label>
    <div>
        <textarea name="rSteps"  placeholder="Recipe Instructions" required> </textarea>
    </div><br/>

    <label>Fat: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rFat"  placeholder="Recipe fat" required>
    </div><br/>

    <label>Carbs: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rCarb"  placeholder="Recipe carbs" required>
    </div><br/>

    <label>Protein: <span style="color: #FF0000">*</span></label>
    <div>
        <input type="text" name="rPro"  placeholder="Recipe protein" required>
    </div><br/>
    <button type="submit" name="addRecipe">Add Recipe</button>
</form>

The PHP file:

<?php

    include 'connect.php'; 
    if(isset($_POST['addRecipe']))
    {    
        $rName  = $_POST['rName'];
        $rDisc  = $_POST['rDisc'];
        $rImg   = $_POST['rImg'];
        $rCategory  = $_POST['rCategory'];
        $rTotalCalories = $_POST['rTotalCalories'];
        $rServing   = $_POST['rServing'];
        $rTime  = $_POST['rTime'];
        $rIngre = $_POST['rIngre'];
        $rSteps = $_POST['rSteps'];
        $rFat = $_POST['rFat'];
        $rCarb = $_POST['rCarb'];
        $rPro = $_POST['rPro'];
        $pageName = $_POST['pageName'];
        
         $sql = "INSERT INTO recipes ( rName, rDisc, rImg,  rFat, rCarb, rPro, rTotalCalories, rTime, rIngre,
                                        rSteps, rCategory, rServing, pageName)
         VALUES ('$rName', '$rDisc', '$rImg', '$rFat', '$rCarb', '$rPro', '$rTotalCalories', 
                '$rTime', '$rIngre ', '$rSteps', '$rCategory', '$rServing', '$pageName')";
         if (mysqli_query($conn, $sql)) {
            echo "New record has been added successfully !";
         } else {
            echo "Error: " . $sql . ":-" . mysqli_error($conn);
         }
         mysqli_close($conn);
    }
?>

<?php
    $pageName = $_POST['pageName'];
    $newpagecontent = '<html><head><title></title></head><body><p>J</p></body></html>';
    $file = fopen($pageName . '.php', "x");
    fwrite($file, $newpagecontent);
?>

It does work and creates a new page but the content won't show up and the URL bar doesn't have a .php extension it just gives this error: Not Found The requested URL was not found on this server. Please any help?


Solution

  • To mitigate SQL injection attacks you should always use a Prepared Statement when using any data potentially editable by the user, in this instance it is the contents from the POSTed form.

    The stages below are to initially ensure that ALL the required variables are present in the POST array before creating the basic SQL command. The variables are used to construct an array of values which in turn is used to help build the types string that is used in the bind_param step. Both are then supplied to bind_param prior to the execute method being called.

    To generate the HTML page the filesystem (absolute) path and the web path can be deduced and used in the writing of the new HTML page and then the redirection to that new page.

    It is not clear from the above PHP if the database tasks and then the new page creation are done within the same script. In this code it is all a single script/page - the database tasks were not tested but the new page is generated OK.

    <?php
        if( isset(
            $_POST['addRecipe'],
            $_POST['rName'],
            $_POST['rDisc'],
            $_POST['rImg'],
            $_POST['rCategory'],
            $_POST['rTotalCalories'],
            $_POST['rServing'],
            $_POST['rTime'],
            $_POST['rIngre'],
            $_POST['rSteps'],
            $_POST['rFat'],
            $_POST['rCarb'],
            $_POST['rPro'],
            $_POST['pageName']
        )) {
        
            require 'connect.php'; 
            
            # prepare data for insert - in same order as columns in sql below.
            $args=array(
                $_POST['rName'],
                $_POST['rDisc'],
                $_POST['rImg'],
                $_POST['rFat'],
                $_POST['rCarb'],
                $_POST['rPro'],
                $_POST['rTotalCalories'],
                $_POST['rTime'],
                $_POST['rIngre'],
                $_POST['rSteps'],
                $_POST['rCategory'],
                $_POST['rServing'],
                $_POST['pageName']
            );
            # create a string of variable type identifiers for the prepared statement.
            $types=str_repeat( 's', count( $args ) );
            
            # prepare the sql command with placeholders
            $sql='INSERT INTO recipes 
                ( rName, rDisc, rImg, rFat, rCarb, rPro, rTotalCalories, rTime, rIngre, rSteps, rCategory, rServing, pageName )
                VALUES
                ( ?,?,?,?,?,?,?,?,?,?,?,?,? )';
                
            $stmt=$conn->prepare( $sql );
            $stmt->bind_param( $types, ...$args );
            $stmt->execute();
            $stmt->close();
            $conn->close();
            
            #---------------------------------
            # basic HTML template for new page
            $template='
            <html>
                <head>
                    <title>%s</title>
                </head>
                <body>
                    %s
                </body>
            </html>';
            
            # Find current url & remove filename
            $script=explode( '/', $_SERVER['SCRIPT_NAME'] );
            array_pop( $script );
            
            # What is the newly generated HTML / PHP page to actually contain???
            $content=implode('<br />',$_POST );
            
            # Create suitable filepath to save HTML to
            $html=sprintf( $template, $_POST['pageName'], $content );
            $file=sprintf( '%s/%s.php', __DIR__, $_POST['pageName'] );
            
            # Create suitable webpath for browser to navigate to
            $url=sprintf('%s/%s.php', implode('/',$script), $_POST['pageName'] );
            
            # write the content and redirect to new page
            file_put_contents( $file, $html );
            exit( header( sprintf( 'Location: %s', $url ) ) );
        }
    ?>
    <!DOCTYPE html>
    <html lang='en'>
        <head>
            <meta charset='utf-8' />
            <title>POST & Build HTML</title>
            <style>
                label > span{ color:#FF0000 }
                label > span + input,
                label > span + textarea{ display:block; clear:left; }
                form > div{ margin:0.5rem 0; }
            </style>
        </head>
        <body>
        
    
        <form method='post' enctype='multipart/form-data'>
            <div>
                <label>Page Name <span>*</span>
                    <input type='text' name='pageName' placeholder='Page name' required />
                </label>
            </div>
            <div>
                <label>Recipe Name <span>*</span>
                    <input type='text' name='rName' placeholder='Recipe name' required />
                </label>
            </div>
            <div>
                <label>Recipe Discription:<span>*</span>
                    <input type='text' name='rDisc' placeholder='Recipe Description' required />
                </label>
            </div>
            <div>
                <label>Recipe Image:<span>*</span>
                    <input type='text' name='rImg' placeholder='Recipe Image' required />
                </label>
            </div>
            <div>
                <label >Recipe Category: <span>*</span>
                    <input type='text' name='rCategory' placeholder='Recipe Category' required />
                </label>
            </div>
            <div>
                <label>No. of Calories: <span>*</span>
                    <input type='text' name='rTotalCalories' placeholder='Recipe Calorie' required />
                </label>
            </div>
            <div>
                <label>No. of Servings: <span>*</span>
                    <input type='text' name='rServing' placeholder='Recipe Servings' required />
                </label>
            </div>
            <div>
                <label>Cook time: <span>*</span>
                    <input type='text' name='rTime' placeholder='Cook time' required />
                </label>
            </div>
            <div>
                <label>Recipe Ingredients: <span>*</span>
                    <textarea name='rIngre' placeholder='Recipe Ingredients' required></textarea>
                </label>
            </div>
            <div>
                <label>Recipe Instructions: <span>*</span>
                    <textarea name='rSteps' placeholder='Recipe Instructions' required></textarea>
                </label>
            </div>
            <div>
                <label>Fat: <span>*</span>
                    <input type='text' name='rFat' placeholder='Recipe fat' required />
                </label>
            </div>
            <div>
                <label>Carbs: <span>*</span>
                    <input type='text' name='rCarb' placeholder='Recipe carbs' required />
                </label>
            </div>
            <div>
                <label>Protein: <span>*</span>
                    <input type='text' name='rPro' placeholder='Recipe protein' required />
                </label>
            </div>
            
            <button type='submit' name='addRecipe'>Add Recipe</button>
        </form>
        
        
        </body>
    </html>