View Full Version : Fwrite(), multi-line strings, and parse errors

04-27-2012, 08:44 AM
On my website I want a user to be able to more-or-less create a new webpage that will be an actual HTML or PHP file within the website. Although you can just keep passing variables to a new web page it is my understanding that this is bad for Search Engine Optimization purposes. If the web pages needed to be large (for instance, like IMDb pages or Wikipedia pages) then the fact that it's not a "permanent" page and uses too many server variables could seriously hurt its ranking and I would think even make it hard for the search engine to crawl that specific page to show in search results later.

I was recently reading up on how to use PHP to create an entirely new file and found the fopen() and fwrite() functions but there seems to be very little documentation and examples for these functions, especially when using in conjunction with multi-line strings.

As an example I am trying to write a script that uses the user's input of a description which, for simplification, I will use as the entity_name, entity_location and entity_description. Here is my code:

require ('includes/config.inc.php');
$page_title = 'Dataconia | Write Test #2';
$page_description = 'A test for the writing of new pages within Dataconia';
require ('includes/header.html'); //will need header file regardless of what content ends up loading

if (isset($_POST['submitted']))
{// Start of main $_POST conditional +1 = 1
require (MYSQL);
//Trim all field of the post / form
$trimmed = array_map('trim', $_POST);
//Assume invalid values
$uid = $en = $c = $ed = $write_entity_script = $description_reduced = FALSE;
$errors = array(); // Initialize an error array.
//Validate User
if (!isset($_SESSION['user_id'])) // if post is submitted and user_id is not set
echo '<p class="error">You must be logged in to submit a new entity</p>';
} else { $uid = $_SESSION['user_id']; //if post is submitted and user_id IS set
if (isset($_POST['description'])) { //if post is submitted, user_id is set, and entity_name is set, and characters are valid
//&& preg_match('/^[!#$&-;=?-[]_a-z~]+$/' , $_POST['entity_name']
$d = mysqli_real_escape_string ($dbc, $trimmed['description']);
} else { // if post is submitted, user_id is set, but entity_name not set
echo '<p class="error">Please enter a valid name for the entity you are trying to submit. Please be aware that the entity name may not include certain special characters.</p>';
} // end of else clause for no entity name

if ($uid && $d) { // If everything's OK... //+1 = 2
$q = "SELECT entity_description FROM entities WHERE entity_description = '$d'";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
if (mysqli_num_rows($r) == 0 ) { // then the space is available //+1 = 3, Add the user to the database:
$q = "INSERT INTO entities (entity_name, entity_location, entity_description, date_of_creation, created_by) VALUES ('$d', '$d', '$d', NOW(), '$uid' )";
$r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc)); // Close of mysqli_num_rows positive
if (mysqli_affected_rows($dbc) == 1) { // If it ran OK. +1 = 3

$write_entity_script = <<<BETWEEN
require_once ('includes/config.inc.php');
$page_title = 'Dataconia ' . $d; //define page title as site name (Dataconia) with entity name
$description_reduced = substr($d, 0, 200); //define the reduced description as the first 200 characters of the description entered by the user within the 'description' field.
$page_description = "Dataconia | " . $description_reduced . "submission by user of new organization within the Dataconia database";
$page_keywords = $d . ", company, organization, Dataconia, quantifying perception, brands, products, description, reviews";
$page_author = "Kylan Hurt";

echo '<h2>' . $d . '</h2>';
echo '<p>Location: ' . $d . '</p>';
echo '<p>' . $d . '</p>';

fwrite('entities/' . $d . '.php', $write_entity_script);
echo 'Your script has run, please check to see if the file has been written.';

echo '<p>Thank you for your submission. The new submission should show up in our system momentarily.</p>';
include ('includes/footer.html');
exit(); // Stop the page.
} else {//if mysqli_affected_rows is not 1
echo '<p class="error">Your submission could not be processed at this time due to a system error. We apologize for any inconvenience.</p>';
} else { // the entity name is not available +1-1 = 2
echo '<p class="error">The entity name that you entered has already been submitted. Please try submitting a different entity.</p>';
} else { //
echo '<p class="error">Please fill out the form again.</p>';}


} //end of true conditional for the post being submitted

<form action="write_test_2.php" method="post">
<textarea rows="15" cols="60" name="description"></textarea>
<input style="text-align:center;" type="submit" name="submit" value="Submit New Entry" /></p>
<input type="hidden" name="submitted" value="TRUE" />

Notice that I am using php tags within php due to the writing of the multi-line string ($write_entity_script) which starts and ends with word "BETWEEN". Trying to run this script as a whole has given the a parse error:

An error occurred in script '/home/kylhur/danconia.us/write_test_2.php' on line 58: fwrite(): supplied argument is not a valid stream resource.
Date/Time: 4-26-2012 20:49:43

fwrite() is only used once in this file (I tried bolding it but the PHP code formatting for this forum wouldn't let me). For the record the directory that it's writing to (entities/______.php) should have the permissions set up correctly. In fact from PUTTY:
drwxrwxrwx 2 kylhur pg4691404 4096 Apr 23 18:47 entities

SO I am pretty much to the point where I need some serious help with this issue. Any help would be appreciated. I apologize for the poor formatting of my code!

04-27-2012, 05:12 PM
Not sure if this handling will really help you. SEO has come a long way and you can always use rewriting to make it clearer. You can also store information in the db and tie it to a single search cache identifier. Handling files is faster than db usage so long as its done properly, but I'm not sure I'd build page after page for some sort of matching either.

The problem with the fwrite is the usage. The first parameter has to be a resource stream to a file opened with fopen.

if ($fp = @fopen('entities/' . $d. '.php', 'w+'))
fwrite($fp, $write_entity_script);
die('Failed to open file for writing');

file_put_contents can also be used instead which would be closer to what you want to use. It takes a filename, and data, and optionally a write method and stream context.

04-28-2012, 05:58 AM
Fou-Lu, dude, you completely rock! I have officially created my first dynamically-created PHP file (as opposed to webpage)!

I totally did not think I would solve this problem by today, I owe you big time. I even checked the file's contents and it was written correctly.

Again, thanks a ton.