PHP Cheatsheet
Table of Contents
- Related Posts
- Get File Handle For Output Stream
- Write To Stderr
- Regular Expressions
- Destructuring Assignment
- Output CSV File
- Read Password Input From Terminal
- HTTP Basic Auth
- References
Related Posts
Get File Handle For Output Stream
There are many useful functions in the standard library that expect a file handle to write to, but you want to output the the output stream instead. An easy solution for this is to get a handle on the output stream like so:
$fileHandle = fopen("php://output", 'w');
Then you can do something like:
$fileHandle = fopen("php://output", 'w');
$myArray = ["hello", "world"];
fputcsv($fileHandle, $myArray);
Feel free to read more on streams in case you want to do anything funky with the input stream etc.
Write To Stderr
If you are writing a CLI script and something goes wrong, you may wish to output to stderr rather than normal stdout when something goes wrong, so they will appear in error logs etc.
fwrite(STDERR, "You messed up..." . PHP_EOL);
Byte Order Mark
If you are ever generating CSV files for Excel users, you probably want to insert a byte order mark at the very start in order to tell Excel that the content is in UTF-8 format. I find it easiest to just define the byte order mark and then use it when necessary like below:
define('BYTE_ORDER_MARK', "\xEF\xBB\xBF");
Regular Expressions
This regex tutorial is particularly useful for this section.
The following can be used to mean "any kind of letter" (e.g. languages have funky characters not in a-zA-Z).
\p{L}
The following means any kind of whitespace character
\p{Zs}
The following means any kind of number
Below is a regular expression for a line that must be alphanumeric with spaces, underscores and hyphens with 4 or more characters (4 spaces would pass though):
/^[0-9a-zA-Z-_ ]{4,}$/
If you support foreign languages, then you may wish to use the following to allow any type of letter:
/^[\p{L}\p{N}-_ ]{4,}$/u
/u
tells PHP to enable unicode mode in PHP and this will not work on funky letters if you don't have it.
Destructuring Assignment
As of PHP 7.1, you can do the following to rapidly set variables based on the properties of an object/array.
$testArray = ['dog' => 1, 'cat' => 2];
list('dog' => $a, 'cat' => $b) = $testArray;
print "value of a is: {$a}" . PHP_EOL; // outputs 1 from $testArray['dog']
Be Warned, if a value is not set, you will get PHP notices, rather than an exception. E.g.
$test_arr = ['dog' => 1, 'cat' => 2, '' => 3];
list('chow' => $a) = $test_arr;
print "value of chow is: {$chow}" . PHP_EOL;
For that, you will get the following output:
php > $test_arr = ['dog' => 1, 'cat' => 2, '' => 3];
php > list('chow' => $a) = $test_arr;
PHP Notice: Undefined index: chow in php shell code on line 1
php > print "value of chow is: {$chow}" . PHP_EOL;
PHP Notice: Undefined variable: chow in php shell code on line 1
value of chow is:
Output CSV File
define('BYTE_ORDER_MARK', "\xEF\xBB\xBF");
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=output-filename.csv");
header("Pragma: no-cache");
header("Expires: 0");
$fileHandle = fopen("php://output", 'w');
$myArray = ["hello", "world"];
fwrite($fileHandle, BYTE_ORDER_MARK); // for Excel users
fputcsv($fileHandle, $myArray);
die();
Read Password Input From Terminal
This is useful if you want to get a password from the user safely (don't show the characters as they type).
function getPassword($prompt = "Enter Password:")
{
echo $prompt;
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
return $password;
}
HTTP Basic Auth
You can implement http basic auth support in PHP, with the same effect as using the htaccess file. This allows you more flexibility, and resolves an issue with htaccess whereby if you were to connect over http and had http to https redirection enabled, it would ask for your username and password before it would redirect you to https, thus causing you to be prompted twice, and the first time being over an insecure connection.
Below is an example PSR-15 middleware that will require the user to enter the basic auth
<?php
use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Server\RequestHandlerInterface;
use \Psr\Http\Message\ResponseInterface;
class MiddlewareHttpBasicAuth implements \Psr\Http\Server\MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (AuthService::getInstance()->isLoggedIn())
{
$response = $handler->handle($request);
}
else
{
if(!isset($_SERVER['PHP_AUTH_USER']))
{
$response = new \Slim\Psr7\Response(401);
$response = $response->withHeader('WWW-Authenticate', 'Basic realm="My Realm"');
// the body is shown if the user clicks cancel at the prompt for entering username/password
$body = $response->getBody();
$body->write('Goodbye!');
$response = $response->withBody($body);
}
else
{
if
(
$_SERVER['PHP_AUTH_USER'] === HTTP_BASIC_AUTH_USER
&& password_verify($_SERVER['PHP_AUTH_PW'], HTTP_BASIC_AUTH_PASSWORD_HASH)
)
{
AuthService::getInstance()->setLoggedIn();
$response = $handler->handle($request);
}
else
{
// login failed, re-prompt for the details.
// Alternatively, you may wish to show a login failed message here.
$response = new \Slim\Psr7\Response(401);
$response = $response->withHeader('WWW-Authenticate', 'Basic realm="My Realm"');
$body = $response->getBody();
$body->write('Goodbye!');
$response = $response->withBody($body);
}
}
}
return $response;
}
}
References
- Stack Overflow - Destructuring assignment in php for objects / associative arrays
- Dev.to - Reading Passwords from STDIN in PHP
- PHP Manual - HTTP Authentication
First published: 16th August 2018