Biting off more than I can chew… first PHP project

For my first PHP project, while I learn this PHP/MySQL thing, I’m creating a sort of Social Media website…. users register and join, upload photos, make friends, send messages, etc… This project will use a lot of web technologies to make it work… SQL, Mail, File Uploading, Security, Forms, etc.

So far, I’ve been progressing steadily with my personal project and I’m at the point where I can create database-driven websites for paying clients, if I need to… and I’m only what?… about 2 weeks into learning PHP/MySQL.

That’s why for my first project, I picked something that is a little more complex with lots of database JOINS and database interaction. If I can do everything I need to do on my little project, then taking on projects for other people should be easy peasy.

Don’t get me wrong, I’ve been creating complex sites using ASP… so this is not really a “first” project for me… but it is my first “real”, “working” PHP website. So for me,  it’s just a matter of finding the equivalent PHP function or command to do something similar I do with ASP.

For this project, I’m also using Google Maps… and it’s actually easier interfacing with Google Maps using PHP rather than ASP… since Google provides examples in PHP (but none in ASP).

Talking about “biting off more than I can chew”…. I’m investigating using Code Igniter to use as my PHP Framework.  This is something totally new to me… and it looks like CI will be interesting and will make creating websites easier and faster… I think I’ll finish this project first, then later on convert it to CI for version 2.0.

Last month, I was thinking of buying Expression Engine (costs $300+) and now I’m glad I didn’t… since now I’m just creating the whole website from raw PHP without the use of Expression Engine…. but from what I read, EE uses CI…. so I think down the road, I may use EE for future projects. But I think it’s nice to learn the nuts and bolts of PHP and really get deep into the code, before I start using EE or CI… this will make me appreciate more CI and also have an idea of how to make it work using raw PHP code.

Posted in Uncategorized | Comments Off on Biting off more than I can chew… first PHP project

ASP Response.Redirect vs. PHP Header location

My old ASP habits are sometimes hard to break… I like the simpler redirect equivalent of ASP compared to the PHP header location command:

// redirect to thank you page
 header( 'Location: /thankyou.php' ) ;

So… I just made a function and put it in my include/common.php file.

// Function: Redirect()
// Description: Redirect user to another page/url, similar to ASP Response.Redirect()
function Redirect($url) {
   header( 'Location: ' . $url ) ;    
} // function Redirect

So now, I can just use the simpler and easier to remember:

Redirect('/thankyou.php');
Posted in Uncategorized | Comments Off on ASP Response.Redirect vs. PHP Header location

PHP Session Handling vs. ASP Session Handling

Just because you created a session variable in PHP, using this statement:

session_start();

 // store session variables to designate that the user is successfully logged in! 
 $_SESSION["login"] = TRUE;
 $_SESSION["username"] = $varUserName;    

doesn’t mean you can automatically access the $_SESSION(“login”) variable from another program!

In ASP, once the session variable is created, you’re good to go and can access it immediately from any other program.

value = Session("username")   ' this works fine in ASP, no need for a session_start()

In PHP, you must also use the command

session_start();

before you can use the $_SESSION variable you created…

So session_start() is not just needed when you want to create a new session variable, it’s also needed when you want to access your session variables.

I guess I should put this command in my include/common.php file, so it’s always available to me and not have to worry about whether it was set or not.  Just session_start it automatically for all users!

Posted in Uncategorized | Comments Off on PHP Session Handling vs. ASP Session Handling

ASP Response.Redirect vs. PHP Header location

Be careful that you don’t have any extra blank spaces in the PHP file… if you try to do a “redirect”, you’ll get an error.

<?php
//****************** INCLUDE *******************
include('include/common.php');
include('include/dbconnect.php');
?> 

<?php
// check if form submitted
if ($_SERVER['REQUEST_METHOD'] == "POST") {....
header( 'Location: /index.php' );     // this will be an error

This instead will be fine.

<?php
//****************** INCLUDE *******************
include('include/common.php');
include('include/dbconnect.php');
?>
<?php
// check if form submitted
if ($_SERVER['REQUEST_METHOD'] == "POST") {

The only difference? …. notice there is no blank line between ?> and <?php

… also, starting a session will also fail?

Warning:  session_start() [function.session-start]: Cannot send session
cache limiter - headers already sent (output started
at /VirtualHosts/TestSite/login.php:6)

Warning:  Cannot modify header information - headers already sent
by (output started at /VirtualHosts/TestSite/login.php:6)
in /VirtualHosts/TestSite/login.php on line 56

All these errors, just because of that blank line… so be careful!

Posted in Uncategorized | Comments Off on ASP Response.Redirect vs. PHP Header location

PHP Error Reporting

It’s possible to enable or disable display of error messages in your PHP program by using the command

error_reporting(‘some constant’);     // see below for values of constant

Errors and Logging
Value Constant Description Note
1 E_ERROR (integer) Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.
2 E_WARNING (integer) Run-time warnings (non-fatal errors). Execution of the script is not halted.
4 E_PARSE (integer) Compile-time parse errors. Parse errors should only be generated by the parser.
8 E_NOTICE (integer) Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.
16 E_CORE_ERROR (integer) Fatal errors that occur during PHP’s initial startup. This is like an E_ERROR, except it is generated by the core of PHP. since PHP 4
32 E_CORE_WARNING (integer) Warnings (non-fatal errors) that occur during PHP’s initial startup. This is like an E_WARNING, except it is generated by the core of PHP. since PHP 4
64 E_COMPILE_ERROR (integer) Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine. since PHP 4
128 E_COMPILE_WARNING (integer) Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine. since PHP 4
256 E_USER_ERROR (integer) User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function trigger_error(). since PHP 4
512 E_USER_WARNING (integer) User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function trigger_error(). since PHP 4
1024 E_USER_NOTICE (integer) User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function trigger_error(). since PHP 4
2048 E_STRICT (integer) Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. since PHP 5
4096 E_RECOVERABLE_ERROR (integer) Catchable fatal error. It indicates that a probably dangerous error occured, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also set_error_handler()), the application aborts as it was an E_ERROR. since PHP 5.2.0
8192 E_DEPRECATED (integer) Run-time notices. Enable this to receive warnings about code that will not work in future versions. since PHP 5.3.0
16384 E_USER_DEPRECATED (integer) User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function trigger_error(). since PHP 5.3.0
30719 E_ALL (integer) All errors and warnings, as supported, except of level E_STRICT. 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously

The above values (either numerical or symbolic) are used to build up a bitmask that specifies which errors to report. You can use the bitwise operators to combine these values or mask out certain types of errors. Note that only ‘|’, ‘~’, ‘!’, ‘^’ and ‘&’ will be understood within php.ini.

— end of paste —

While it’s nice to disable display of error messages, for example:

Notice: Undefined index:….

which allows me to use the $_POST command and mimics the behaviour of ASP, it may cause more headaches during debugging because of typos.

For example: This mimics the behavior of ASP with regards to handling of form values. i.e. no errors when you try to access a form variable that has not been POSTED yet.

error_reporting(E_ERROR);
echo "<p>new error status: " . ini_get('error_reporting');
echo "<br>about to POST";
$varUserName = $_POST["frmUserName"];
echo "<p>";
error_reporting(E_NOTICE);echo "<br>About to POST";
 $varUserName = $_POST["frmUserName"];

OUTPUT as follows:

new error status: 1
about to POST
new error status: 8
About to POST
Notice: Undefined index: frmUserName in /VirtualHosts/TestSite/TMP1JKJKENQ3Y.php on line 13

The PROBLEM is if I mistype something in the program, example, $_POST… there won’t be any error message displayed.

<?php
error_reporting(E_ERROR);
echo "<p>new error status: " . ini_get('error_reporting');
echo "<br>about to POST";
$varUserName = $_POSTs["frmUserName"];
echo "<p>";
error_reporting(E_NOTICE);echo "<br>About to POST";
$varUserName = $_POST["frmUserName"];
 ?>

In this second example, the typo was $_POSTs (with an extra “s”). It returns the same result as the first example:

new error status: 1
about to POST
new error status: 8
About to POST
Notice: Undefined index: frmUserName in /VirtualHosts/TestSite/TMP1NH4TENQ93.php on line 13

I think I should just “suck it up” and enable all error reporting, and that would force me to write a “cleaner” and less “sloppy” code… one in which PHP will be all happy, without any errors or undefined variables, etc..

Posted in Uncategorized | Comments Off on PHP Error Reporting

SQL Injection — How to sanitize your user forms.

SQL injection… I hate this. I’ve been a victim of this once and it caused me a lot of work… (not too much, I just restored the database from the previous day). Anyway, since then I always use my general input ‘cleaning’ routine where all data that come from forms are “cleaned” and sanitized.

In ASP, I replace all single quote marks with null, and also scan the string for “Hot Words” and remove them, or kill the program.

Here’s my new PHP equivalent.

// Description: Use this to clean user input
function CleanInput($str) {
 // if $strHotWords detected, die()
 $strHotWords = "CAST(|<IFRAME|<SCRIPT";
 $strHotWords = explode("|",$strHotWords);
 for($i=0;$i<count($strHotWords);$i++) {        
 if (strpos(strtolower($str),strtolower($strHotWords[$i])) !== false) {
    $str = '';    // blank it
    die ('');    // don't display any clue to hackers
 } // end if
 } // for

 // replace bad characters
 //$bad  = array("'","-","=",'"','%','='," ");
 //$good = array ("","","","","","","");
 //$str  = str_replace($bad,$good,$str);

 // for good measure, escape string
 return mysql_real_escape_string($str);
} // function

Uncomment the code after //replace bad characters if you want to be AGGRESSIVE in cleaning your input strings.

All quote, dash, equal, single quote, and spaces are replaced with empty strings. Now, there’s absolutely no way any valid SQL Injection could be created!

Posted in Uncategorized | Comments Off on SQL Injection — How to sanitize your user forms.

How to check for EOF in MySQL

In ASP, I can check for an End-Of-File condition by using

rs.EOF     ' returns True or False

For example, if I’m verifying if a certain UserName exists in the database, I can do a SELECT * FROM query, and check if rs.EOF.  If it’s rs.EOF, then I know the UserName is unique in the database.

In PHP/MySQL, to check for an end-of-file condition, count the number of rows returned by the query.

$query = "SELECT UserName FROM UserDB WHERE UserName='$UserName'";
$result = mysql_query($query);
// is a match found?
if (mysql_num_rows($result)){
  // match is found in UserDB, not unique name
  return FALSE;
} else {
  return TRUE;
}
Posted in sql | Comments Off on How to check for EOF in MySQL

My first “real” PHP program! User Registration

I think I just created my first “real” PHP program.

It’s a User Registration Form which does the following:

  • checks if username entered is at least 4 char long
  • the email address entered is valid format (but no checking if real or fake)
  • the password is at least 6 char long
  • and matches the verify password field
  • the username entered is unique, and not already used
  • sends an email confirmation to user with a random code
  • and displays a thank you message for a successful registration
  • else display an error page with the specific error message

Next program to do is the verification program. I plan to embed the URL in the email confirmation message. All the user need to do is click on it.

Posted in Uncategorized | Comments Off on My first “real” PHP program! User Registration

MySQL $query format

In MySQL, you can create your query string like this:

$query = "INSERT INTO NameDB (field1, field2, ....) VALUES ('$value1', '$value2',....)";

Note that $values must be enclosed in quotes, otherwise you get an SQL error.

In a way, this is easier than building query strings in ASP/MSSQL where you have to concatenate strings and variables. In PHP, you can use the variable name within the string ($value1, $value2)… just make sure to put quote marks around it.

Posted in Uncategorized | Comments Off on MySQL $query format

Move to first record of table

In ASP, we use

rs.MoveFirst

In PHP, we need to use:

// go back to top
mysql_data_seek($result, 0);        // first row number is 0
Posted in Uncategorized | Comments Off on Move to first record of table