Table of Contents

PHP Programming

PHP is a web-native language that essentially embeds itself within HTML.

While the wiki is still being built, refer to: https://www.devdungeon.com/topics/php and https://github.com/DevDungeon/Cookbook/tree/master/php

Installing

In Debian and most Linux distributions, it's as simple as using the package manager:

apt install php php-pdo-sqlite
php --version
 
# For Apache2 httpd
apt install apache2 libapache2-mod-php

See the web servers page for more info on configuring

Built-in webserver

PHP has a built-in web server that is useful for local developing and testing.

# Serves current directory, no directory listing
php -S localhost:9999
 
# Specify path to serve
php -S localhost:9999 -t /path/to/serve

Phar files

Phar files are essentially tarballs of PHP content. In addition to the convenience of having a single .phar containing many files, the phar can be marked executable and treated like an executable Java JAR. See the official phar documentation.

It can be treated as a special protocol for referencing files like this: phar://myphar.phar/file.php You can read or include files in this manner.

Composer

Composer is an optional tool for managing depedencies.

See: https://www.devdungeon.com/content/php-composer-basics

Code examples

Here are some snippets for reference.

Hello world

Here is a simple “Hello world” application.

hello.php
<?php
echo "Hello, world!";

PHP info

php_info.php
<?php
// Show all PHP configs/extensions
phpinfo();

Show all errors

show_errors.php
<?php
// Add this to turn on all errors (disable in production!)
 
// The ini_set options could also go in php.ini
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Functions

functions.php
<?php
 
function greet($name, $greeting="Hi") {
  print("$greeting, $name!");
}
 
greet("NanoDano");  // Hi, NanoDano!

Include a PHP file

load_lib.php
<?php
// Pick one method for loading another PHP file
include('my_lib.php'); // Include if available
require('my_lib.php'); // Fail if not available
require_once('my_lib.php'); // Ensure not loaded twice

Forms

form.php
<html>
<body>
 
<?php
if ($_POST['something']) {
  print("Received: " . $_POST['something'];
}
 
<form method="post">
  <input type="text" name="something" id="something" />
  <br />
  <button type="submit">Submit</button>
</form>
 
</body>
</html>

Redirect

Use the PHP function header() to send a new Location header.

redirect.php
<?php
// Set HTTP header to redirect
// Must go before any content is output
header('Location: /'); // Defaults to 302
 
// Or specify status code
//header('Location: /', TRUE, 301);
 
exit; // If you want to ensure nothing else gets output

SQLite database

This example is for SQLite3 using the PHP PDO_SQLITE, but essentially the same for other databases too.

apt install php-pdo-sqlite

sqlite_example.php
<?php
 
// Connect (Use `sqlite::memory:` for memory-only)
$db = new PDO('sqlite:'.__DIR__.'/bookmarks.sqlite3');
 
// Create table
$db->exec(
"CREATE TABLE IF NOT EXISTS urls (
    url TEXT,
    notes TEXT
    )"
);
 
// Prepared statement for changes
$query = $db->prepare('INSERT INTO urls (url) VALUES (?)');
$query->execute(['https://www.devdungeon.com/']);
 
// Query
$result = $db->query('SELECT * FROM urls');
foreach ($result as $result) {
    print($result['url'].'<br />');
}
 
$db = null;  // Close it

libgit2

See: https://www.devdungeon.com/content/how-perform-git-operations-php

Crop images

crop_image_gd.php
// Crop using GD (`apt install php-gd`)
$src_img = imagecreatefrompng('300x200.png');
if(!$src_img) {
    die('Error when reading the source image.');
}
$thumbnail = imagecreatetruecolor(200, 200);
if(!$thumbnail) {
    die('Error when creating the destination image.');
}
// Take 200x200 from 200x200 starting at 50,0
$result = imagecopyresampled($thumbnail, $src_img, 0, 0, 50, 0, 200, 200, 200, 200);
if(!$result) {
    die('Error when generating the thumbnail.');
}
$result = imagejpeg($thumbnail, '200x200gd.png');
if(!$result) {
    die('Error when saving the thumbnail.');
}
$result = imagedestroy($thumbnail);
if(!$result) {
    die('Error when destroying the image.');
}
crop_image_imagick.php
// Crop image using Imagick (`apt install php-imagick`)
$inFile = "300x200.png";
$outFile = "200x200_imagick.png";
$image = new Imagick($inFile);
$image->cropImage(200,200, 50,0);
$image->writeImage($outFile);

JSON

json.php
<?php
# PHP object -> JSON string
$json_string = json_encode(['my_key' => 'my value', 'other_key' => 'other value']);
echo $json_string;
 
# JSON string -> PHP object
$json_string = '{"my_key":"my value","other_key":"other value"}';
$my_array =  json_decode($json_string);
print_r($my_array)
 
// Dump/read from file
file_put_contents('test.json', json_encode([2, 4, 6]));
$my_array = json_decode(file_get_contents('test.json'));
print_r($my_array);

Sockets

TCP server

tcp_server.php
<?php
$socket = stream_socket_server("tcp://192.168.1.5:8000", $errno, $errstr);
if (!$socket) {
  echo "$errstr ($errno)\n";
  die('Could not create socket');
}
 
while (true) {
  while ($conn = stream_socket_accept($socket, -1, $peername)) {
    fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
    echo "Connection received from: $peername\n";
    fclose($conn);
  }
}
 
fclose($socket);

Generate SSL certificate

make_ssl_cert.php
<?php
$certificateData = array(
    "countryName" => "US",
    "stateOrProvinceName" => "Texas",
    "localityName" => "Houston",
    "organizationName" => "Example.com",
    "organizationalUnitName" => "Development",
    "commonName" => "My Company",
    "emailAddress" => "example@example.com"
);
 
// Generate certificate
$privateKey = openssl_pkey_new();
$certificate = openssl_csr_new($certificateData, $privateKey);
$certificate = openssl_csr_sign($certificate, null, $privateKey, 365);
 
// Generate PEM file
$pem_passphrase = 'abracadabra'; // empty for no passphrase
$pem = array();
openssl_x509_export($certificate, $pem[0]);
openssl_pkey_export($privateKey, $pem[1], $pem_passphrase);
$pem = implode($pem);
 
// Save PEM file
$pemfile = './server.pem';
file_put_contents($pemfile, $pem);

SSL server

ssl_server.php
<?php
$context = stream_context_create();
 
// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert', $pemfile);
 
// Pass Phrase (password) of private key
stream_context_set_option($context, 'ssl', 'passphrase', $pem_passphrase);
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);
 
// Create the server socket
$socket = stream_socket_server(
    'ssl://0.0.0.0:9001',
    $errno,
    $errstr,
    STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,
    $context
);
 
// fwrite/fread to $socket

SSL client

ssl_client_simple.php
<?php
// Simple SSL client
$socket = stream_socket_client("ssl://192.168.1.2:5522", $errno, $errstr);
if ($socket) { echo fread($socket, 2000); }
ssl_client_full.php
<?php
$host = '192.168.1.2';
$port = 5522;
$timeout = 30;
$cert = 'e:\www\workspace\php\sockets\server.pem';
$context = stream_context_create(
    array('ssl'=>array('local_cert'=> $cert))
);
if ($socket = stream_socket_client(
        'ssl://'.$host.':'.$port,
        $errno,
        $errstr,
        30,
        STREAM_CLIENT_CONNECT,
        $context)
) {
    fwrite($socket, "\n");
    echo fread($socket,8192);
    fclose($socket);
} else {
   echo "ERROR: $errno - $errstr\n";
}

Tail a file

tail.php
<?php
// The flushing may be affected by your web server and your browser
// and how much data they require before they will flush the buffer.
$handle = popen("tail -f /path/to/file 2>&1", 'r');
while(!feof($handle)) {
    $buffer = fgets($handle);
    echo "$buffer<br/>\n";
    ob_flush();
    flush();
}
pclose($handle);

Simple HTTP request

http_get.php
<?php
$data = file_get_contents("https://www.devdungeon.com/");
print($data);

cURL requests

Install php-curl on Debian. cURL lets you make all kinds of requests, not just HTTP. See my tutorial: cURL Tutorial.

curl_example.php
<?php
// apt install php-curl
$curlHandle = curl_init("http://www.devdungeon.com/");
$filePointer = fopen("output.txt", "w");
 
// Set options before executing
curl_setopt($curlHandle, CURLOPT_FILE, $filePointer); // Output to file instead of STDOUT
curl_setopt($curlHandle, CURLOPT_HEADER, 1); // Include headers
curl_setopt($curlHandle, CURLOPT_VERBOSE, 1); // Output extra details
 
// Execute and clean up
curl_exec($curlHandle);
curl_close($curlHandle);
fclose($filePointer);
 
// Other available options
/*
CURLOPT_VERBOSE // 1 if you want Curl to give detailed reports about everything that is happening.
CURLOPT_URL // String containing the URL you want Curl to fetch.
CURLOPT_USERAGENT // A string containing the "user-agent" header to be used in a HTTP request.
CURLOPT_TIMEOUT // A number equal to the maximum time in seconds that Curl functions can take.
CURLOPT_NOBODY // 1 to tell Curl not to include the body part in the output. For HTTP(S) servers, this is equivalent to a HEAD request - only the headers will be returned.
CURLOPT_POST // 1 if you want Curl to do a regular HTTP POST.
CURLOPT_POSTFIELDS // A string containing the data to post in the HTTP "POST" operation.
CURLOPT_COOKIE
CURLOPT_COOKIEFILE
CURLOPT_USERPWD // A string formatted in the username:password manner, for Curl to give to the remote server if requested.
CURLOPT_RESUME_FROM // A number equal to the offset, in bytes, that you want your transfer to start from.
CURLOPT_FOLLOWLOCATION // 1 to follow Location: headers
CURLOPT_MAXREDIRS // limits FollowLocations
CURLOPT_REFERER // A string containing the "referer" header to be used in an HTTP request. This is only necessary if the remote server relies on this value.
CURLOPT_FAILONERROR // 1 for silent fail
CURLOPT_FTPAPPEND // append not overwrite
CURLOPT_FTPLISTONLY // 1 to list just the names of an FTP directory as opposed to more detailed information.
CURLOPT_HTTPHEADER //An array of HTTP header fields to be set.
CURLOPT_INFILE // String containing the filename where the input of your transfer comes from.
CURLOPT_INFILESIZE //The size of the file being uploaded to a remote site.
CURLOPT_CRLF // convert unix to CRLF new lines
CURLOPT_RETURNTRANSFER // 1 if you want Curl to return the transfer data instead of printing it out directly.
CURLOPT_STDERR // A string containing the filename to write errors to instead of normal output.
CURLOPT_UPLOAD // 1 if you want PHP to prepare for a file upload.
CURLOPT_WRITEHEADER // containing the filename to write the header part of the output into.
*/