Misc PHP Info

Learning PHP

PHP the Right Way is a great resource when first getting started with PHP.

The best book I've found for learning PHP, and other things, is Learning PHP, MySQL, JavaScript, & CSS by Robin Nixon. The table of contents pages are here. The sample code is here. Chapter 16 is especially good for Form processing.

Configuration for Development

Settings

 

Handling Notices

Instead of using falsy logic, it is better to explicitly check to see if a variable is first set. Otherwise, PHP will generate a Notice error. This can be fixed as follows:

  1. if (isset($_GET['barrier'])) {
  2. if ($_GET['barrier']==='closed') {
  3. echo 'alert("Access to that course has been suspended.");' . PHP_EOL;
  4. }
  5. }

Alternatively, using the array_key_exists() function may work better. As in:

array_key_exists('barrier',$_GET)

Classes and functions()

Function Arguments

Normally, when you pass a variable into a function, it is done “by value”. If you want to pass a variable “by reference”, then prefix the variable name with an ampersand.

  1. function titleCase(&$name, $isAwesome = false) {
  2. $name = ucfirst(strtolower($name));
  3. if ($isAwesome) {
  4. $name .= ' is awesome!';
  5. }
  6. $myName = "CrAiG";
  7. titleCase($myName);
  8. echo $myName; //Craig
  9.  
  10. titleCase($myName, true);
  11. echo $myName; //Craig is awesome!

Creating an Empty Object

To create an empty object (similar to what Javascript does with myObject = {};), you can use:

$myObject = new stdClass();

or

$myObject = (object) null;

Creating an Empty Array

$myArray = array();

To add items to the end of the array leave the array index blank, for example:

$myArray[] = $newItem;

Forms

To call the same page that the form is on, use this action attribute.

  1. <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="POST">

Passing Data

To pass data (via GET variables) the function http_build_query($queryData) may come in handy. For example:

  1. $myGetVariables['pageId'] = 14;
  2. $myGetVariables['action'] = 'rebuild';
  3. header('Location: mypage.php?' . http_build_query($myGetVariables));

Which results in the url mypage.php?pageId=14&action=rebuild

Headers

You will often find the need to call one PHP page, but return a different one. PHP’s equivalent of the HTML statement
document.location = "http://www.myDomain.com"; /* Javascript */ is
header('Location: http://www.myDomain.com'); /* PHP code */

PHP’s header function will only accept a fully qualified filename, but you can mimic relative paths using this code:

  1. $host = $_SERVER['HTTP_HOST']; //domain name (no trailing slash)
  2. $uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\'); //folder containing this page (no trailing slash)
  3.  
  4. //modify the $uri to go up one level
  5. $uriArray = explode("/",$uri);
  6. unset($uriArray[count($uriArray) - 1]); //remove the last item in the array (i.e. go up one level)
  7. $uri = implode("/",$uriArray); //reassemble the string
  8.  
  9. $extra = 'myNewPage.php';
  10.  
  11. header("Location: http://$host$uri/$extra");

Echo

There are a few ways to write code out to your web page. The first is a single line echo like:

  1. $variable = 'cats';
  2. echo "<p>I enjoy $variable.</p>"; //I enjoy cats.

Because the previous line uses double quotes, variable names will be replaced with their contents. Using a single quote would result in: I enjoy $variable.

heredoc Syntax

In the previous example, variables can be resolved or not, depending on the use of double or single quotes. The same is true when defining Strings using heredoc and nowdoc syntax.

  1. <?php
  2. $variable = 'cats';
  3. echo <<<END
  4. <div>
  5. <h1>My Header</h1>
  6. <p>I enjoy $variable.</p> //resolves the variable
  7. </div>
  8. END;
  9. ?>

The previous block of code will resolve the variable, whereas the next will not.

nowdoc Syntax

The difference is the single quotes around the word END. You can use any word after the <<<, just make sure you use the same word to mark the end of your block. The ending marker must also start in the first column and can be the only thing on that line.

  1. <?php
  2. $variable = 'cats';
  3. echo <<<'END'
  4. <div>
  5. <h1>My Header</h1>
  6. <p>I enjoy $variable.</p> //will not resolve the variable
  7. </div>
  8. END;
  9. ?>

Another Option

If you are conditionally echoing a large chunk of HTML, then this syntax will probably be easier to use.

  1. <?php if ($lovesCakes): ?>
  2. <div>
  3. <h1>Pancake Master</h1>
  4. <p>I enjoy making pancakes.</p>
  5. </div>
  6. <?php endif; ?>

In this example I used PHP’s Alternative Syntax for Control Structures. You could also use the standard curly brace syntax. Many people feel the code is easy to read the Alternative Syntax when mixing PHP and other languages (HTML, CSS, Javascript, etc.).

Includes

Let’s say your directory structure looks like this:

Specifying the location of your include files can get a bit tricky because the location of the file is relative to the page called by the browser. Certainly not a problem if page A includes page B; but when A includes B, and B includes C, and C includes B, and all these files are in different directories; well then you'll have references to files that can not be resolved. This strategy works pretty well to make sense of it all.

1. Organize your directory structure.

Arrange your files such that browser-facing files (such as index.php) are anywhere except the “includes” directory. The files inside “includes” should never be called from the browser address bar.

2. Create some PHP constants that define the location of the “include” folder.

common.php will contain the magic bit of code that tells other other files where to find the includes. This would also be a great place to put your database connection information. Note to self: See the GEM project for an example.

  1. //dirname(__FILE__)); //get the directory location of this included file
  2. define('APP_ROOT', dirname(dirname(__FILE__))); //double-pumping to go up one level since this is in a sub-directory.
  3. define('INCLUDE_ROOT', APP_ROOT . "/php/");

3. Use the common.php file.

Our new constants (APP_ROOT and INCLUDE_ROOT) won’t do any good unless you get them into your web pages; therefore, all files that need an include will first need a hard-coded reference to common.php. This applies to both browser-facing files such as index.php and files called via AJAX such as actions/insertRecord.php.

Example: In index.php you would have:

  1. <?php
  2. require_once 'includes/common.php';
  3.  
  4. //Build the page structure
  5. require_once INCLUDE_ROOT . 'htmlFragments/header.php';
  6. require_once INCLUDE_ROOT . 'htmlFragments/main.php';
  7. require_once INCLUDE_ROOT . 'htmlFragments/footer.php';
  8.  
  9. ?>

Notice that once common.php has been loaded, you can start to use the constant INCLUDE_ROOT. All “require” and “include” statements use INCLUDE_ROOT.

Let’s say studentRecords.php uses an instance of the Student class, defined in student.php, and it calls a method in course.php.

studentRecords.php is:

  1. <?php
  2. require_once 'includes/common.php';
  3. require_once INCLUDE_ROOT . 'classes/Student.php';
  4.  
  5. //Build the page structure
  6. require_once INCLUDE_ROOT . 'htmlFragments/header.php';
  7. require_once INCLUDE_ROOT . 'htmlFragments/main.php';
  8.  
  9. $s = new Student("Craig");
  10. $s->showCourses();
  11.  
  12. require_once INCLUDE_ROOT . 'htmlFragments/footer.php';
  13.  
  14. ?>

Student.php would start out like this:

  1. <?php
  2. require_once INCLUDE_ROOT . 'classes/course.php';
  3.  
  4. class Student {
  5. public function showCourses() {
  6. $courseArray = Course::getCourses($this->studentId);
  7. //echo out the list of courses for this student
  8. }
  9. }
  10. ?>

The require_once will work because INCLUDE_ROOT was already brought in by studentRecords.php. This is why it is vital that no file inside the “includes” directory are ever called directly.

Variables and Constants

Variables are defined simply by referencing them. All variable must begin with a $ character. Ex: $myVar = 1;

To reference a variable variable name, enclose it in curly braces. e.g. $pr->{'response'.($idx + 1)} = $guess; Here I am setting an instance variable (for example, $pr->response1, $pr->response2, $pr->response3, etc.) value to $guess.

Constants are defined with the PHP function define(). Ex: define("MY_CONSTANT", 3.14159); By convention, constants are usually in all upper-case. To use your constant, just reference its name. i.e. $pi = MY_CONSTANT;

Pre-defined “Magic” Constants

PHP comes with some constants already for you to use (they are prefixed and suffixed with double underscores):

__LINE__ : The current line number of the file.

__FILE__ : The full path and filename of the file. If inside an include, then the include's filename is used.

__DIR__ : Directory of the file.

__FUNCTION__ : The function's name

__CLASS__ : The class name.

__METHOD__ : The class method name.

__NAMESPACE__ : The current namespace.

Variable Scope

Variables are visible only within the area in which they are defined. If you would like a global variable to be visible to a function, then use the global keyword as in the following example.

  1. $db = new PDO($dbDSN, $dbUserId, $dbPassword);
  2. $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  3.  
  4. function showDbInfo() {
  5. global $db;
  6. echo $db->getAttribute(PDO::ATTR_CONNECTION_STATUS);
  7. }
  8. showDbInfo();

Handling Dates with PHP and MySQL

This section has not been written yet. I have some notes in my green folder and an example is in the Intel Solution Architect 2013 project. See claimform/index.php.

Information from Richard Lord’s blog post (click here to view)

 

phpinfo()

The phpinfo() function returns data about your PHP installation. This function will generate a complete, fully-formed web page, so start with a blank file, name it something like "info.php" and put this in it:

  1. <?php
  2. phpinfo();
  3. ?>

Security

OWASP Zed Attack Proxy can be used to test the security vulnerabilities of your web app.

Survive the Deep End: PHP Security is a great resource for learning how to secure your site.