updated 2020-05-11.
PHP is now the most popular servers-side scripting language in the world. It is, in fact, the programming component of the “LAMP” environment: Linux, Apache, MySql, Php and is built in to all major linux distributions.
PHP is surprisingly more popular than Microsoft’s own ASP web scripting language! PHP initially started on Linux/unix environment but today there are more PHP developers on MS Windows platform than on unix. The newer versions of PHP, precisely PHP 7.0 onwards have improvised for better security, performance, and scalability. PHP is also used for large-scale applications and the biggest example of which is the Facebook application. Top PHP frameworks, based on popularity and ability to facilitate application development: 1. Laravel, 2. CodeIgniter, 3. Symfony, 4. CakePHP, 5. Yii, 6. Zend, …
* PHP 5 implemented OOP, but it also made changes which broke old code and so many web hosting co’s continued to maintain PHP 4 along with PHP 5. PHP 6 was supposed to add native unicode support to PHP. Eventually many of the new features intended for PHP 6 were back-ported to the PHP 5.x branch. Mysqli, requiring new parameters, was introduced in PHP 5.1 and in 5.6 a warning was issued. PHP 7 came next, skipping 6 entirely, showing an almost 100% increase in performance, but decisions were made that caused backward-compatibility breaks. Significantly, mysql was dropped, breaking all code still using the mysql functions. most web hosting providers [in 2019] maintain 5.6 and 7.x.
Also, there are both free frameworks and free templates that go a long way to simplify coding and separating code from html mark-up, display; website design vs. content.
PHP frameworks help to promote rapid application development (RAD), which saves you time, helps build more stable applications, and reduces the amount of repetitive coding for developers. Frameworks can also help beginners to build more stable apps by ensuring proper database interaction and coding on the presentation layer. This allows you to spend more time creating the actual web application, instead of spending time writing repetitive code.
Activating and de-activating the php processor
The pair of opening and closing tags to activate the php processor are <?php and ?>
if you are embedding PHP within XML or XHTML (almost everything has been xhtml … till html5) you will need to use the <?php ?> tags to remain compliant with standards. It is, therefore, the only universal and recommended tag.
Common variations on the “if” syntax
the { and the } enclose a block of (multiple lines of) code
if (condition) { $id = $newid ; $pw = $newpw ; } else { $id = $oldid ; $pw = $oldpw ; }
only one line of code each can be used for the if and the else, without the {}’s
if (condition) $counter++; else $counter--;
a nice simple syntax is:
if (condition):
#multiple lines
else:
#multiple lines
endif;
while (condition):
#multiple lines
endwhile;
<?php if ( condition ): ?>
lots of html
<?php else: ?>
lots of html
<?php endif; ?>
As the manual points out, the method of breaking out of PHP is more efficient when dealing with large sections of HTML. Because there is less work for the parser.
You can start a conditional or loop and “finish it later”.
Like start an if statement, exit to html, and then at the end, re-open php and close the bracket for the if statement – no echo needed.
EX:
<?php if ($a == $b) { ?>
|— lots of html —| (where a = b)
<?php } ?>
This abbreviated syntax is common. In fact, it seems to be the norm, often taken to an extreme. (see some open-source pkgs for examples)
< ?php if ($a == $b): ?> |--- lots of html ---| if a = b < ?php endif; ?>
if ():
. . .
endif;
This can eliminate a lot of lines of { and } and look cleaner, easier to read.
Also it is more explicit.
example:
for($day = 1; $day <= $daysInMonth; $day++):
if( ($day + $offset - 1) % 7 == 0 && $day != 1):
echo "</tr><tr>";
$rows++;
endif;
echo "<td align=right>" . $day . "</td>";
endfor;
while( ($day + $offset) <= $rows * 7):
echo "<td></td>";
$day++;
endwhile;
for():
. . .
endfor;
foreach():
. . .
endforeach;
while():
. . .
endwhile;
“do until”
do {
. . .
} while() ;
ex: the 1st record has already been read, header info from it
has been displayed, now inside the loop, display the details of each record.
not recommended but to watch out for:
$c = ($a==$b) ? ‘it is true’ : ‘it is false’;
ex.:
$cell_type = ($row==1) ? ‘th’ : ‘td’; # in a table.
and
the alternative syntax (: … endif;) may be needed inside
a function and otherwise, not recommended.
and yet others, not easy to follow, not straight-forward:
print(‘$a is ‘.($a > $b ? ‘bigger than’ : ($a == $b ? ‘equal to’ : ‘smaller than’ )).’ $b’);
Don’t do it. When you have to comprehend a program quickly, you won’t appreciate it.
better:
IF – ELSE:
echo '$a is ';
if ($a > $b) { echo 'bigger than ' ; }
elseif ($a == "$b"){ echo 'equal to ' ; }
else { echo 'smaller than ' ; }
echo $b ;
if ($i == 0) { echo "i equals 0"; } elseif ($i == 1) { echo "i equals 1"; } elseif ($i == 2) { echo "i equals 2"; }
$t=date("H"); #24 hrs if ($t<"12") { echo "Have a good morning!"; } elseif ($t<"20") { echo "Have a good day!"; } else { echo "Have a good night!"; }
this does look easier to read:
$t=date("H"); #24 hrs if ($t<"12"): echo "Have a good morning!"; elseif ($t<"20"): echo "Have a good day!"; else: echo "Have a good night!"; endif;
Case Statement (switch)
$destination = "New York";
echo "Traveling to $destination <br />";
switch ($destination){
case "Las Vegas":
echo "Bring an extra $500";
break;
case "Amsterdam":
echo "Bring an open mind";
break;
case "Egypt":
echo "Bring 15 bottles of SPF 50 Sunscreen";
break;
case "Tokyo":
echo "Bring lots of money";
break;
case "Caribbean Islands":
echo "Bring a swimsuit";
break;
default:
echo "Bring lots of underwear!";
break;
}
switch($value) {
case 1:
case 2:
echo "the value is either 1 or 2";
break;
}
switch ($p) {
case 'home':
case '':
$current_home = 'current';
break;
case 'users.online':
case 'users.location':
case 'users.featured':
case 'users.new':
case 'users.browse':
case 'users.search':
case 'users.staff':
$current_users = 'current';
break;
case 'forum':
$current_forum = 'current';
break;
}
switch ($p) {
case 'home':
$current_home = 'current';
break;
case 'users.online' || 'users.location' || 'users.featured' ||
'users.browse' || 'users.search' || 'users.staff':
$current_users = 'current';
break;
case 'forum':
$current_forum = 'current';
break;
}
if there is no “break”, then all actions following the first case matched will be executed. The control flow will “falls through” all subsequent case, and execute all of the actions under each subsequent case, until a break; statement is encountered, or until the end of the switch statement is reached.
** How to test for a variable **
if (isset($var)) {
echo ' $var = '.$var ;
}
$var = ”;
// Evaluates as true because $var is set
if (isset($var)) {
echo ‘$var is set even if it is empty ‘;
}
** How to send (yourself?) a simple email **
$msg = 'First line of text \n Second line of text';
mail('someone@example.com','My subject',$msg);
** How to handle cookies **
This function should be called before tag.
setcookie(name, value, expire, path, domain, security);
to see a cookie
if ( isset($_COOKIE["name"]) )
echo $_COOKIE["name"]. "
";
to delete a cookie set the cookie with a date that has already expired
Set the expiration date to one hour ago
setcookie("name", "", time() - 3600);
or
setcookie( "name", "value", time()- 3600, "/","", 0);
New PHP-5.x functions to
ACCESS A DATABASE
“Old MySQL extension officially deprecated since PHP 5.5.0 in late 2012 and it was removed after PHP 5.6. The alternatives since PHP 5 and later are MySQLi (“i” stands from “improved”)
Old extension didn’t support “Prepared Statements”.
Prepared Statements are very important for web application security, as they protect from SQL injection. Using Prepared Statements you do not have to escape strings before insert them in Database.”
example
$DBHost = 'localhost' $DBUser = 'DB_USER'; $DBPass = 'DB_PASSWORD'; $DBName = 'DB_NAME'; $socket = mysqli_connect($DBHost, $dDBUser, $DBPass ); if (isset($socket)) : $db_select = mysqli_select_db($socket, $dbNAME ) ; if (!$db_select) { $msg = "Database $dbNAME failed: " . mysqli_error() ; } endif; $query = 'SELECT col1, col2, col3 FROM table1 WHERE condition'; ------- $result = mysqli_query($socket, $query); ------- while ($qRow = mysqli_fetch_object($result)) echo ' col1='.$qRow->col1.' col2='.$qRow->col2.' col3='.$qRow->col3.' ' ; ------- mysqli_error($socket) ------- mysqli_num_rows($resulta) ------- mysqli_affected_rows($socket) ; ------- ------- $recordkey = @mysqli_insert_id($socket); ------- # Get the new record key that was "auto-insert"ed.
How to get a list of files from a folder
example, open the current dir
if ($filelist = opendir('.'))
{
while ($picture = readdir($filelist))
{
if (strpos($picture, '.jpg') !== false)
{ echo ' <img src="'.$picture.'"> <br> '.$picture.'<br> <br> <br>' ; }
}
closedir($handle);
}
See Also
is_dir() – Tells whether the filename is a directory
readdir() – Read entry from directory handle
dir() – Return an instance of the Directory class
Open A File – to read and-or write to it
fopen(filename,mode)
mode:
“r” Read only. Starts at the beginning of the file
“r+” Read/Write. Starts at the beginning of the file
“w” Write only. Opens and clears the contents of file; or creates a new file if it doesn’t exist
“w+” Read/Write. Opens and clears the contents of file; or creates a new file if it doesn’t exist
“a” Write only. [append] Opens and writes to the end of the file or creates a new file . . .
“a+” Read/Write. [append] Preserves file content by writing to the end of the file
“x” Write only. Creates a new file. Returns FALSE and an error if file already exists
“x+” Read/Write. Creates a new file. Returns FALSE and an error if file already exists
Note: When writing to a text file, be sure to use the correct line-ending character.
Unix systems use \n, Windows systems use \r\n, and Macintosh systems use \r as the line ending character.
$file = fopen(“test.txt”,”r”);
$file = fopen(“/home/test/test.txt”,”r”);
$file = fopen(“http://www.example.com/”,”r”);
Debugging
If your program totally dies; if you are getting a blank screen with no errors, you may have a syntax error. The quickest way to check your syntax is to use PHP’s own built-in edit-check. From a command line, go to where the program is, and then use the command
php -l [name-of-your-program] <cr>
-l … the parameter is the letter L (lower case), not a number 1.
Otherwise, you need the display of PHP’s error messages enabled, at the top of your program, if you are the only one running the program. Something like this:
ini_set('display_errors', 1); ini_set('log_errors', 1); ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); error_reporting(E_ALL ^ E_NOTICE);
how to Debug on a web site
If your program is already “in production”, and that is the only quick place to find the error and fix it, put an if statement around the above block of code that spells out ONLY your IP address. Errors will display for ONLY YOU:
Display your IP address first, if you don’t know it. On the web site, each visitor will see their ip address, not yours. In the top of the program, or another program, put
your IP address is <?php echo getenv("REMOTE_ADDR"); ?>
Then, replace that line with your block that turns on error reporting just for you!:
( use YOUR ip address! )
if ('123.45.67.8' == getenv("REMOTE_ADDR") ) { ini_set('display_errors', 1); ini_set('log_errors', 1); ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); error_reporting(E_ALL ^ E_NOTICE); }
# comment it out when you don’t need it, but in any case, no one but you will get your debug error messages.
Structured display of All Variables in memory
“The function, get_defined_vars(), returns a multidimensional array containing a list of all defined variables at that location in your program.”
To get ALL variables, list ALL variables, display ALL variables, in memory and available at the point where you request it, your scope, (not just SESSION variables, everything … except private function variables – invisible/unavailable externally).
To get more than just a string of names and values, but a readable, structured list, use
echo '<pre>';
print_r ( get_defined_vars() ) ;
echo '</pre>';
For a long time, I have been displaying the variables in memory with
print_r( get_defined_vars() );
and getting a slammed, long wrapped lines, hard to read, string of so many variables and values that wrapped around line after line. Now I have discovered that putting “pre” around it formats it with indenting even. Very nice. (above)
Even nicer, instead of print_r(), use var_dump(). It not only displays values in colors, it also displays the variable type (string, int, boolean, etc.) for each one.
echo '<pre>';
var_dump ( get_defined_vars() );
echo '</pre >';
for me, it also displays boolean (false (0)) values that did not show up before. Only the boolean “true” (“1”) was showing up for me. (I don’t know if this is true of anyone else)
In all cases, the GLOBAL variables (almost all of them) are getting displayed twice – in my v5.2 anyway.
$_SESSION variables are not included.
You might place get_defined_vars(), both inside and outside a function to see the difference.
or
echo '< pre >'.
“This way you don’t get rendered HTML.” (if it’s an issue)
htmlspecialchars(print_r(get_defined_vars(), true)).
'< /pre >';
You can also display only session variables: print_r($_SESSION)
;
print_r($_POST);
print_r($_GET);
also see
get_defined_constants()
get_defined_functions()
see
$_SERVER['HTTP_HOST']
$_SERVER["SERVER_NAME"]
dirname(__file__)
dirname($_SERVER['SCRIPT_FILENAME'])
Calling other programs, common functions
To include common blocks of code, in several of your programs.
The two functions, include and require, are identical in every way, except errors cause the program to teminate with “require” but not with “include”:
“once” will prevent accidentally loading the same included file more than once.
include('config.php')
include_once('config.php')
will generate a warning, but the script will continue execution if the included file is not found.
require('config.php')
require_once('config.php')
will generate a fatal error, and the script will stop execution if the included file is not found.
call another program and then leave this one:
header('Location: folder/page-x.php');
exit;
remember, output buffering is needed (top-of-the-program) or there can be no output before this header.
Otherwise, the header will not run and there will be no error message!
see output buffering, below.
Also, the current program will continue running unless you “exit;”! Important to know-remember!
ending a block of php code or the whole program
“The closing tag of a block of PHP code automatically implies a semicolon; you do not need to have a semicolon terminating the last line of a PHP block.”
“The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it is helpful when using include() or require(), so unwanted white-space will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering…”
– http://php.net/manual/en/language.basic-syntax.instruction-separation.php
output buffering
output buffering will speed up program processing and avoid some programming errors
The “headers already sent” error occurs when you call session_start after you have already sent some content to the browser. Event an empty line at the start of the file is considered as content and will cause error.
ob_start();
# start Output Buffering (to the browser)
While output buffering is active no output,except the headers, is sent from the script. The output is stored in the buffer and sent to the browser at the end of the script. You can also send the buffer’s contents to the browser by calling ob_flush or ob_end_flush
ob_flush();
# – send the buffer’s contents to the browser
ob_get_contents() – Return the contents of the output buffer
ob_clean() – Clean (erase) the output buffer
ob_end_flush() – Flush (send) the output buffer and turn off output buffering
ob_end_clean() – Clean (erase) the output buffer and turn off output buffering
strings with variables:
$Variables (and “\n”) ARE PARSED (interpolated) inside DOUBLE quotation marks (“), but are NOT parsed inside single quotation marks (‘).
Functions, such as plural(), are not parsed.
EXample1:
$count = 5 ;
echo 'There are $count marbles';
# = There are $count marbles
vs
echo "There are $count marbles";
# = There are 5 marbles
vs
echo 'There are '.$count.' marbles';
# = There are 5 marbles
however, given
$num1=1
$num2=2
echo ' '.$num1.' + '.$num2.' = '.$num1 + $num2 ;
will not display ” 1 + 2 = 3″ instead, it will simply echo the answer, “3”
this
echo ' Q: '.$num1.' + '.$num2.' = '.$num1 + $num2 ;
will echo “2” of all things!
this works:
echo ' '.$num1.' + '.$num2.' = '.($num1 + $num2) ;
it will echo ” 1 + 2 = 3″
Explanation: php will not concatenate strings and evaluate expressions (a + b etc.) in one echo statement, without putting parentheses around the variables/terms to be evaluated.
EXample2:
$dog = ‘Beagle’;
of course you cannot echo the variable plural like this: $dogs
ex: echo " He walked the $dogs ";
// won’t work, s is a valid char for variable names
echo “find the $dog’s water dish”; // works, because ‘ is an invalid char for variable names
of course, the easiest is to separate the variable:
echo ' He walked the '.$dog.'s ';
and
echo "He walked the {$dog}s";
// works
echo "He walked the ${dog}s";
// also works
{ and } tells php to evaluate whatever is inside the { } first.
EXample3:
this:
echo ‘< img src=”images/smile.jif” height=”25px” width=”30px” alt=””>
‘.$title[“i”] ;
not this!:
echo “< img src=\”images/smile.jif\” height=\”25px\” width=\”30px\” alt=\”\”>
“.$title[“i”] ;
$Tag = ‘< h2 style=”color:green;”> Don\’t say “Goodby” < /h2>’;
The html trend was toward requiring double quotes almost everywhere
[“give me a break!”] xhtml will not render many values that are not in required quotes, and java script requires quotes in many situations. With php requiring quotes to delimit those strings of html (and java) you can end up forced to backslash quotes “all over the place”! You can hardly read it anymore!
Therefore
use single quotes around HTML output since html is “littered” with double quotes.
If / where you have variables, concatenate your string(s) around them so that “There are 5 marbles” is written
echo ‘There are ‘.$count.’ marbles’; – in the example above.
PHP has offered an alternative syntax to eliminate the php quotes in long string output:
the trend is toward keeping the php processor out of html as much as possible: put <?php … ?> around the absolute minimum html even though it may mean repeating <?php … ?> many times.
PHP 5.3 introduces a new syntax element, NOWDOC.
The following 3 statements are equivalent:
( the word “echo” can )
( be replaced with “=” ) … don’t do it!
———————————————-
// NOT good programming practice! but, we need to know
// in case we encounter it in someone else’s code
given
$author = "Shakespeare";
this works properly:
echo $author;
this works but is sloppy:
=$author;
this works also but not likely to be encountered?:
="Shakespeare"
CASE STATEMENT
switch ($i) { case 0: echo "i equals 0"; break; case 1: echo "i equals 1"; break; case 2: echo "i equals 2"; break; default: echo "i is greater than 2"; break; }
And … for everyone who wonders
The “missing” ?> tag at the end of various .php program-files is intentional.
As you may know, if you try to run a PHP file which has whitespace (spaces or blank lines etc) after the final ?> then it can cause problems, usually the dreaded “headers already sent” error.
Removing the ?> from php files is a way of mitigating against this error. PHP will quite happily work without it (automatically assuming the closing tag at the end of the file), and thus any whitespace at the end of the file will not cause errors.
………………………………………………….
Note:
The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it, is helpful when using include() or require(), so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.
If you are embedding this in XML, you had better place the ending ‘?>’ there or the XML parser will puke on you. XML parsers do not like processing instructions without end tags, regardless of what PHP does.
If you’re doing HTML like 90% of the world, or if you are going to process/interpret the PHP before the XML parser ever sees it, then you can likely get away with it, but it’s still not best practice for XML.
– http://www.php.net/basic-syntax.instruction-separation
Coding Standards
Some coding standards aren’t so much about performance as they are about making code easier to work with, read, for yourself and for others:
There are many different coding standards in use. Freelance developers need to be familiar with as many as possible, and have the flexibility to code to these standards when called upon to do so. Probably one of the most debated, and when it comes down to it unimportant, features of many coding standards is the way you format your code. Not that code formatting is unimportant, it is very important and, again, can go a long way to make your code look more professional. The part that really doesn’t matter is how you do it. Use 2,3,4 spaces, or some other variation that nobody has thought up yet. (It is becoming recognized that using tabs is a bad idea – if you have not encountered enough problems with it already.) Break your lines, maintaining your indentation! Again, breaking around the 80th column or before 90 or 100 does not matter, just do it and try to be consistent. The point is to format the code. The idea is to make it easier to read the code, so do what you like, or do what is required by your clients/employers, but do it.
Some say “Use Classes rather than function libraries”. Functions actually run slightly faster than class members, but the classes are OO. Classes shouldn’t be in huge files. Break them up and don’t call one unless you need it.
Understand database abstraction layers. The point is, if you’re thrown into a situation where your client is using a database abstraction layer and they believe it is the best practice method then you want to know how they work and what the benefits are. One of the perceived benefits is to centralize the database calls in case there is a problem. If all the database interaction is going through the same code you are much less likely to have one of those sneaky little issues that hides for hours. It can also give the opportunity to add caching and other database wide improvements. Also, when you have to make a change to the database schema, you only have to change the code in one place.
Document your code well. No matter how easy it is for you to understand the flow and function of your code you need to document so that others can understand it. Imagine the next person to look at that code is going to be a first year PHP developer. What will they need to understand so that they don’t break your code? Some times it’s the basic code logic that needs documenting, especially when management is constantly changing the logic (a pet peeve for another time).
Use full PHP open tags! ( Initialize your variables. This is not just a personal opinion, your code will actually run faster if all your variables are initialized before use. It also makes your code look more professional which can make the difference between getting a project/position or not. Leave error reporting on E_ALL for development and testing to get the warnings about uninitialized variables.
Last; This is more of an established rule than a standard: use single quotes whenever you can. They are faster! There is less processing necessary for single quotes so you’re always going to be better off using single quotes. There are times when heredoc, or other double quote type behavior is necessary but save it for when it’s needed.
The idea of these standards are to help separate the men from the boys so to speak. In the programming climate that PHP resides there are a lot of boys, whatever we can do to look more professional is definitely worth it.
http://www.bestcodingpractices.com/php_industry_standards-2894.html
Security on the Internet
1. There is a phpinfo() function which reports a lot of information about your PHP setup. Never put it in a program on you server where any visitor or internet cracking syndicate, “hacker” or “cracker”, can see it – get to it!
the PHP.ini file security settings
display_errors = Off
display_startup_errors = Off
log_errors = On
error_reporting = E_ALL
error_log = /your/path/php-ini-ERROR-LOG.txt
expose_php = Off
short_open_tag = Off
for explanations on these settings, see
http://25yearsofprogramming.com/blog/20070808.htm
Since the release of PHP 5.3.0, these features have been deprecated.
magic_quotes_runtime = Off
magic_quotes_sybase = Off
magic_quotes_gpc = Off
register_globals = Off
By default, allow_url_include is disabled.
allow_url_include = Off
just make sure it is not turned “On” in your php.ini
when you copy the php.ini file to the root of your server, you should also add the lines below to your root .htaccess file – create the file if necessary.
< FilesMatch “\.ini$”>
Deny from all
< /FilesMatch>