PHP General Cheatsheet - everything you need to know

PHP General Cheatsheet

Table of contents for this Cheat sheet: How to manually write your own pagination in PHPWhat are the SPL data structuresWhat are the SPL Iterators in PHP?How do you access the php://input stream?What are PHP's PSRs?What is the max size, by default, of GET variables?When is __destruct called in PHP?What are the main error types in PHPWhat does PEAR stand for?How to check if a object has a static variable defined?How can you check if a variable is alphanum (alphanumeric, letters and numbers only) in PHP?What is snake case?What is camel case?How to set infinite execution time in a PHP scriptWhat is the spaceship operator (<=>) in PHP?How to use Anonymous classes in PHP 7?How to destroy or remove a cookie in PHPHow does PHP compare objects?Is multiple inheritance supported in PHP?How to replace whitespace with a single spaceWhat is the null coalescing operator in PHP7?How to reverse htmlentities() / What is the opposite of htmlentities()?What does 'final class' and 'final function' (final method) mean in PHP?How do you launch the PHP interactive shell?How to view all installed PHP modules?How to find out which php.ini file PHP is using?How do you run a PHP script from the command line?How to query mysql using PDO in PHP?How could you include a custom function for every single time PHP runs?How to check if two strings are anagrams in PHP?

How to manually write your own pagination in PHP

If you use a framework such as Laravel you almost always have some pagination features built in. Here is how to manually write out your own pagination feature in some simple to follow PHP.

For this code I'll still be using Eloquent, part of Laravel. It would be easy to write out the SQL too, so I've included that as well.

Let's begin by working out how many items we have in total

First we need to know the total number of rows that we are working with, and decide how many we will show per page.

  1. $count = BlogPost::count();
  2. $per_page = 15;

This would be the same as: select count(*) as c from blog_posts

Calculate how many pages there will be:

  1. $pages = ceil($count / $per_page);

The ceil() function will round up to the next full integer. So if $count/$per_page was 4.1, it would return 5.

Also, get the current page!

We need to decide what page the user is currently on. The first page would be page 1 (so be sure to remember to hard code that, even if $_GET['page'] (or whatever you use) is not set. I will hard code it in though...

  1. $current_page = (int) 8; // ensure it is an integer!
  2. if ($current_page < 1) {
  3.     $current_page = 1;
  4. }
  5. if ($current_page>$pages) {
  6.     $current_page = $pages;
  7.     // or really, do a HTTP temporary redirect to that page
  8. }

Here we set the current page (but you could replace the 8 with $_GET['page'] ?? 1 (which will be the value of 'page' in the url (for example yoursite.com/your-script.php?page=123) or default to 1.

If the selected page is greater than the number of pages then you should do something like show 404 error, just show the max page's content (which is what the code above does), redirect to another page, or just show 'nothing found' (like a soft 404 error).

Oh, and of course you want to check that the current page is no smaller than 1!

Now you want to decide how many items 'along' you want to start from... (LIMIT startfromhere, takethismany, or LIMIT takethismany OFFSET startfromhere).

  1. $current_page_from = ($current_page - 1) * $per_page;

Putting it all together

Now we have everything we need!

If you are using a ORM like eloquent, you can do something like this:

  1. $rows = BlogPost::orderBy("id", "asc")->skip($current_page_from)->take($per_page)->get()

This would generate something like this (for page 8, 15 per page): select * from `interview_question_q_and_as` order by `id` asc limit 15 offset 105.

The reason I am focusing on providing Eloquent code and not really playing with SQL direct is because this is a beginners topic (pagination), and I really don't recommend beginners start off with direct SQL as there are so many SQL injection attacks that you will probably leave yourself open for attack with. Always use prepared statements, don't put any variables direct in SQL. I'll have a guide soon explaining everything....

Pagination links

Don't forget to include pagination links. This will simply loop through them all. You might want to modify it to show prev/next links. If you have a a.active { font-weight:bold;} css rule, the current page will be highlighted.

  1. for($i=1;$i<=$pages;$i++) {
  2.     $active = ($i === $current_page) ? " class='active' " : "";
  3.     echo "<a href='?page=$i' $active>Page $i</a> ";
  4. }

How to do it in Laravel's Eloquent

  1. // it automatically works out what page you are on
  2. $posts = BlogPost::paginate(15);
  3.  
  4. foreach($posts as $post) {
  5.     // cycle through the posts
  6. }
  7.  
  8.  
  9. // creating the clickable links...
  10.  echo $posts->appends( [] )->links();

You can use the array in appends() to automatically include any url parameters.

(for example, if your url was /?page=3&search_for=ducks, you should do appends(['search_for']) to ensure that it gets included in your pagination links.

View More Details (and 10 discussions about this topic) Here...

What are the SPL data structures

The SPL (Standard PHP Library) includes several data structures that you should be aware of and hopefully use. Here is an overview of them:

SplDoublyLinkedList — The SplDoublyLinkedList class - this provides the main functionalities of a doubly linked list

SplStack — The SplStack class - this provides the main functionalities of a stack implemented using a doubly linked list.

SplQueue — The SplQueue class - this provides the main functionalities of a queue implemented using a doubly linked list.

SplHeap — The SplHeap class - this provides the main functionalities of a Heap.

SplMaxHeap — The SplMaxHeap class - this provides the main functionalities of a heap, keeping the maximum on the top.

SplMinHeap — The SplMinHeap class - this provides the main functionalities of a heap, keeping the minimum on the top.

SplPriorityQueue — The SplPriorityQueue class - this provides the main functionalities of a prioritized queue, implemented using a max heap.

SplFixedArray — The SplFixedArray class - this provides the main functionalities of array. The main differences between a SplFixedArray and a normal PHP array is that the SplFixedArray is of fixed length and allows only integers within the range as indexes. The advantage is that it allows a faster array implementation.

SplObjectStorage — The SplObjectStorage class - this provides a map from objects to data or, by ignoring data, an object set. This dual purpose can be useful in many cases involving the need to uniquely identify objects.

View More Details (and 10 discussions about this topic) Here...

What are the SPL Iterators in PHP?

The iterators in the Standard PHP Library (SPL) are the following:

AppendIterator — The AppendIterator class

ArrayIterator — The ArrayIterator class

CachingIterator — The CachingIterator class

CallbackFilterIterator — The CallbackFilterIterator class

DirectoryIterator — The DirectoryIterator class

EmptyIterator — The EmptyIterator class

FilesystemIterator — The FilesystemIterator class

FilterIterator — The FilterIterator class

GlobIterator — The GlobIterator class

InfiniteIterator — The InfiniteIterator class

IteratorIterator — The IteratorIterator class

LimitIterator — The LimitIterator class

MultipleIterator — The MultipleIterator class

NoRewindIterator — The NoRewindIterator class

ParentIterator — The ParentIterator class

RecursiveArrayIterator — The RecursiveArrayIterator class

RecursiveCachingIterator — The RecursiveCachingIterator class

RecursiveCallbackFilterIterator — The RecursiveCallbackFilterIterator class

RecursiveDirectoryIterator — The RecursiveDirectoryIterator class

RecursiveFilterIterator — The RecursiveFilterIterator class

RecursiveIteratorIterator — The RecursiveIteratorIterator class

RecursiveRegexIterator — The RecursiveRegexIterator class

RecursiveTreeIterator — The RecursiveTreeIterator class

RegexIterator — The RegexIterator class

View More Details (and 10 discussions about this topic) Here...

How do you access the php://input stream?

The php://input contains the raw data from a POST request, after all of the HTTP headers. You can think of $_POST as the same data (...sometimes) that has been parsed into an array. php://input gets the raw data. The stream can be accessed in the following way:

  1. $val = file_get_contents("php://input");
View More Details (and 7 discussions about this topic) Here...

What are PHP's PSRs?

PSRs are PHP Standards Recommendations. They are a standard and clearly defined way to do many common tasks.

Some common PSRs:

PSR-0 - Autoloading Standard
This is not in use any more - you should use PSR-4.

It describes the mandatory requirements that must be adhered to for autoloader interoperability.

PSR-1 - Basic Coding Standard

It comprises what should be considered the standard coding elements that are required to ensure a high level of technical interoperability between shared PHP code.

PSR-2 - Coding Style Guide

It considers PSR-1 and it is intended to reduce cognitive friction when scanning code from different authors. It does so by enumerating a shared set of rules and expectations about how to format PHP code.

Some of the basic and main rules:

  • Use spaces, not tabs (4 spaces = 1 tab)
  • The namespace ... should be on its own line
  • The closing ?> must not be present, for files containing only PHP
  • PHP keywords (true, false, null) must always be in lower case
  • The extends and implements must be on the same line as the class name
  • The opening bracket must go on its own (new) line
  • You must always provide a public/protected/private for all object properties. Same for methods.
  • There must be exactly one space after the comma between method or function parameters, and no space before the comma
  • Function and method parameters may be spread over several lines, if you wish
  • And if structures must look like the following:
  1. <?php
  2. if ($expr1) {
  3.     // if body
  4. } elseif ($expr2) {
  5.     // elseif body
  6. } else {
  7.     // else body;
  8. }

You can find the full specs here.

PSR-3 - Logger Interface

It describes a common interface for logging libraries.

PSR-4 - Autoloading Standard

It describes a specification for autoloading classes from file paths. It is fully interoperable, and can be used in addition to any other autoloading specification, including PSR-0. This PSR also describes where to place files that will be auto loaded according to the specification.

PSR-4 is often used with Composer's composer.json to help with autoloading of PHP classes.

PSR-5 - PHPDoc Standard
This spec is only a draft (as of Oct 2018)

The main purpose of this PSR is to provide a complete and formal definition of the PHPDoc standard. This PSR deviates from its predecessor, the de facto PHPDoc Standard associated with phpDocumentor 1.x, to provide support for newer features in the PHP language and to address some of the shortcomings of its predecessor. Is only a draft (as of Oct 2018)

PSR-6 - Caching Interface

The goal of this PSR is to allow developers to create cache-aware libraries that can be integrated into existing frameworks and systems without the need for custom development.

Here are the interfaces - I've removed most of the comments to make this page more readable, but if you want to see full details then please go here.

CacheItemInterface

CacheItemInterface defines an item inside a cache system.

  1. <?php
  2.  
  3. namespace Psr\Cache;
  4.  
  5. // CacheItemInterface defines an interface for interacting with objects inside a cache.
  6. interface CacheItemInterface
  7. {
  8.      // Returns the key for the current cache item.
  9.     public function getKey();
  10.  
  11.      // Retrieves the value of the item from the cache associated with this object's key.
  12.     public function get();
  13.  
  14.      // Confirms if the cache item lookup resulted in a cache hit.
  15.     public function isHit();
  16.  
  17.      // Sets the value represented by this cache item.
  18.     public function set($value);
  19.  
  20.      // Sets the expiration time for this cache item.
  21.     public function expiresAt($expiration);
  22.  
  23.      // Sets the expiration time for this cache item.
  24.     public function expiresAfter($time);
  25.  
  26. }
CacheItemPoolInterface

The primary purpose of Cache\CacheItemPoolInterface is to accept a key from the Calling Library and return the associated Cache\CacheItemInterface object.

  1. <?php
  2.  
  3. namespace Psr\Cache;
  4.  
  5. // CacheItemPoolInterface generates CacheItemInterface objects.
  6. interface CacheItemPoolInterface
  7. {
  8.      // Returns a Cache Item representing the specified key.
  9.     public function getItem($key);
  10.  
  11.      // Returns a traversable set of cache items.
  12.     public function getItems(array $keys = array());
  13.  
  14.      // Confirms if the cache contains specified cache item.
  15.     public function hasItem($key);
  16.  
  17.      // Deletes all items in the pool.
  18.     public function clear();
  19.  
  20.      // Removes the item from the pool.
  21.     public function deleteItem($key);
  22.  
  23.      // Removes multiple items from the pool.
  24.     public function deleteItems(array $keys);
  25.  
  26.      // Persists a cache item immediately.
  27.     public function save(CacheItemInterface $item);
  28.  
  29.      // Sets a cache item to be persisted later.
  30.     public function saveDeferred(CacheItemInterface $item);
  31.  
  32.      // Persists any deferred cache items.
  33.     public function commit();
  34. }
CacheException and InvalidArgumentException

There are two interfaces for exceptions related to PSR-6 that should be used.

CacheException: Exception interface for all exceptions thrown by an Implementing Library

InvalidArgumentException: Exception interface for invalid cache arguments.

PSR-7 explained: HTTP Message Interface

What is PSR-7, and when to use it? PSR 7 is a set of interfaces for HTTP messages and URIs, used when PHP is used as a web server (i.e. over HTTP).

If you want to get an instance of a PSR-7 request in Laravel, then you must use the symfony/psr-http-message-bridge and zendframework/zend-diactoros package. Then you can get a Psr\Http\Message\ServerRequestInterface class automatically injected into your controller methods by type hinting the ServerRequestInterface interface as a method param.

PSR 7 basically describes common interfaces for representing HTTP messages as described in RFC 7230 and RFC 7231, and URIs for use with HTTP messages as described in RFC 3986.

A common package used is the Zend Diactoros one (which is also the one recommended to use if you want to use PSR-7 requests with Laravel. Find more details here.

PSR-9 - Security Disclosure
This spec is only a draft (as of Oct 2018)

It gives project leads a clearly dIt gives project leads a clearly defined approach to enabling end users to discover security disclosures using a clearly defined structured format for these disclosures. Is only a draft (as of Oct 2018)

PSR-10 - Security Advisories
This spec is only a draft (as of Oct 2018)

It gives researchers, project leads, upstream project leadIt gives researchers, project leads, upstream project leads and end users a defined and structured process for disclosing security vulnerabilities. Is only a draft (as of Oct 2018)

PSR-11 - Container Interface
This spec is only a draft (as of Oct 2018)

It describes a common interface for dependency injection containers. The goal is to standardize how frameworks and libraries make use of a container to obtain objects and parameters (called entries in the rest of this document). Is only a draft (as of Oct 2018)

PSR-12 - Extended Coding Style Guide
This spec is only a draft (as of Oct 2018)

It extends, expands and replaces PSR-2, the coding style guide and requires adherence to PSR-1, the basic coding standard. Is only a draft (as of Oct 2018)

Source: Wikipedia's list of all PSRs

View More Details (and 11 discussions about this topic) Here...

What is the max size, by default, of GET variables?

By default the max size for values in the $_GET[] array is 2048 bytes. The $_POST[] has no such limit.

View More Details (and 8 discussions about this topic) Here...

When is __destruct called in PHP?

The __destruct method is called either during the shutdown sequence (i.e. end of execution of a script), or when there are no references to an object.

Remember that if you put a __destruct() method in a subclass, you must call parent::__destruct() if you want the parent's destruct method to execute (assuming there is one).

The method will be called even if exit() is called. However, if exit() is called from within a destructor, then no further destructors will be called.

Note: completely unrelated to Array Destructuring.

View More Details (and 5 discussions about this topic) Here...

What are the main error types in PHP

There are 3 main types of errors: Notices (not very important), Warnings (quite important), and Fatal (so important that the script will halt).

(Please don't ignore Notices just because I said they're not important. It was only to give a comparison between those three. There is often very important information in the Notice errors)

Notices (E_USER_NOTICE) - These are non-critical errors that do not stop further execution of the script (by default). If you try to use a variable that has not been set, you will get an E_USER_NOTICE notice error, but the script will (in default PHP settings) continue to run.

Warnings (E_USER_WARNING) - These are similar to notices, but more important. The script will still run (with default PHP settings), however, you should really pay attention to them. A warning error would be shown (/logged) for things such as attempting to use include() on a file that does not exist.

Fatal Errors (E_ERROR, or E_CORE_ERROR if PHP cannot initialise) - if your scripts encounter a fatal error, it will stop execution. A fatal error comes from doing things such as calling a function that does not exist, or calling require() for a file that does not exist.

View More Details (and 11 discussions about this topic) Here...

What does PEAR stand for?

PEAR stands for 'PHP Extension and Application Repository'

It is a set of packages that provide further functionality than what is just built into plain PHP. It used to be more popular, I would say now that PEAR is quite dead. If you need to install a package, it will normally be a standard package installed with Composer. I remember years ago (10 years ago?) it was common to be working with PEAR packages. In 2018, not so much...

View More Details (and 4 discussions about this topic) Here...

How to check if a object has a static variable defined?

If you have an object and you need to check if it has a const SOME_CONSTANT = 'foo' set, then you can use defined in the following way:

  1.         class ExampleClass {
  2.             const CONST_THAT_DOES_EXIST = 9;
  3.  
  4.             function does_it_have_const() {
  5.             // late static binding:
  6.                 var_dump( defined('static::CONST_THAT_DOES_EXIST') );
  7.                 var_dump( defined('static::CONST_THAT_DOES_NOT_EXIST') );
  8.  
  9.                 // or use self
  10.                 var_dump( defined('self::CONST_THAT_DOES_EXIST') );
  11.             }
  12.  
  13.         }
View More Details (and 9 discussions about this topic) Here...

How can you check if a variable is alphanum (alphanumeric, letters and numbers only) in PHP?

There are a couple of ways to achieve this, both very simple.

The most simple is to use ctype_alnum(). This function has been in PHP since PHP4. The following code would output 'all passed', as all three strings are alphanumeric

  1.             if( ctype_alnum("aBcDeFg1234") &&  ctype_alnum("aaa") &&  ctype_alnum("123") ) {
  2.               echo "all passed";
  3.             }

If you need a bit more flexibility, then you could use regex:

  1. return preg_match('/[^a-z0-9]/i', $input);

In the example above, it adds no real advantage and is slower than ctype_alnum so I would recommend just using ctype_alnum.

If you need to check if alpha numeric, but include underscores and dash (hyphen), then you can use the following regex check:

  1. if(preg_match('/[^a-z_\-0-9]/i', $input))
  2. {
  3. return true;
  4. }
  5. return false;

(Both of these are case insensitive, thanks to the i modifier)

You could also do this:

  1. preg_match('/^[\w-]+$/',$input)

Or even [:alnum:]

  1. preg_match("/[^[:alnum:]\-_]/",$str)
View More Details (and 12 discussions about this topic) Here...

What is snake case?

Snake case is the way of writing words/phrases, where each word is separated by an underscore character. It is often used for variable names. For example $blog_posts is in snake case. Sometimes it is written as snake_case.

See also Camel case (e.g. $camelCaseVariable)

View More Details (and 11 discussions about this topic) Here...

What is camel case?

Camel case is where you write words/phrases so that each word begins with a capital letter (but lower case for the rest of the word), and there is no space (or other punctuation) between words. It is often used for function/method names, or variables. For example showBlogPosts().

(Note: often the first character will be lower case for things like method names and parameters. The first character will often be upper case for class names (e.g. class BlogController {...}.

Other alternatives include kebab-case (all lowercase, separated by a hyphen -). Also known as lisp-case or spinal-case.

There is also Train-Case (lowercase, but first letter uppercase, separated by hyphens).

View More Details (and 9 discussions about this topic) Here...

How to set infinite execution time in a PHP script

Add the following code to set unlimited execution time for a PHP script:

  1. set_time_limit(0)

You can also update max_execution_time in php.ini

If the value is 0, it is actually unlimited. Otherwise it is that number of seconds.

View More Details (and 7 discussions about this topic) Here...

What is the spaceship operator (<=>) in PHP?

The spaceship operator was a new feature in PHP 7. It looks like this: <==>

It will return 0 if both sides are equal. 1 if left is greater. -1 if right is greater.

  1.     var_dump( [
  2.  
  3.         "1 <=> 1" => 1 <=> 1,
  4.         "1 <=> 0" => 1 <=> 0,
  5.         "0 <=> 1" => 0 <=> 1,
  6.         "1 <=> \"1\"" => 1 <=> "1",
  7.         "\"abc\" <=> \"abc\"" => "abc" <=> "abc",
  8.         "\"zzz\" <=> \"abc\"" => "zzz" <=> "abc",
  9.  
  10.         ]);
array(6) {
  ["1 <=> 1"]=> 0
  ["1 <=> 0"]=> 1
  ["0 <=> 1"]=> -1
  ["1 <=> "1""]=> 0
  [""abc" <=> "abc""]=> 0
  [""zzz" <=> "abc""]=> 1
}
View More Details (and 9 discussions about this topic) Here...

How to use Anonymous classes in PHP 7?

PHP 7 introduced a new feature of Anonymous classes. Here is how to use them.

  1. // Pre PHP 7 code
  2. class Logger
  3. {
  4.     public function log($msg)
  5.     {
  6.         echo $msg;
  7.     }
  8. }
  9.  
  10. $util->setLogger(new Logger());
  11.  
  12. // PHP 7+ code
  13. $util->setLogger(new class {
  14.     public function log($msg)
  15.     {
  16.         echo $msg;
  17.     }
  18. });

They are great for mocking, as you can easily write quick classes to do their purposes for a test.

You cannot define an anonymous class without instantiating it at the same time. I.e. when you create an anonymous class, it is instantiated at the same time.

They can extend other classes and use interfaces too.

View More Details (and 11 discussions about this topic) Here...

How to destroy or remove a cookie in PHP

To remove a cookie, you should set its expiry to a date in the past.

  1. setcookie("the_cookie_name", "", time()-(60*60*24*7));
  2. // or also set the path, if it was set with a path:
  3. setcookie("the_cookie_name", "", time()-(60*60*24*7),"/");

And then the next time the user loads a page (or makes a request), their browser will remove the cookie.

You should also clear PHP's 'copy' of the cookie:

  1. unset($_COOKIE["the_cookie_name"]);
View More Details (and 4 discussions about this topic) Here...

How does PHP compare objects?

If two objects are compared with ==, then it will check if:

1) - they are two instances of the same type of class

2) - they have the same properties

3) - and those properties have the same values

  1. $a = new SomeClass();
  2. $a->something = 123;
  3.  
  4. $b = new SomeClass();
  5. $b->something = 123;
  6.  
  7. return $a == $b; // true

If two objects are compared with ===, then PHP will return true only if both variables are pointing to the exact same object (the same instance of the object). Remember that objects are always passed by value.

For example, the following will return true:

  1. $a = new SomeClass();
  2. $a->something = 123;
  3. $b = $a; // $a and $b point to the exact same instance
  4.  
  5. return $a === $b; // true

However, the following (using ===) will return false. If the check was with == then it would return true, as the class type/properties/values are the same

  1. $a = new SomeClass();
  2. $a->something = 123;
  3.  
  4. $b = new SomeClass(); // different instance
  5. $b->something = 123;  // same values
  6.  
  7. return $a === $b; // false
View More Details (and 7 discussions about this topic) Here...

Is multiple inheritance supported in PHP?

Nope! You can extend a class only once. You can, however, use traits.

View More Details (and 8 discussions about this topic) Here...

How to replace whitespace with a single space

If you want to replace multiple whitespace characters (multiple spaces, new lines, etc) with just a single space, use this:

  1. $code = preg_replace('!\s+!', ' ', $code);
View More Details (and 7 discussions about this topic) Here...

What is the null coalescing operator in PHP7?

The null coalescing operator is two question marks: ??. It is used to replace some ternary operations. Here is an example:

  1. // old way
  2. $var = isset($_GET['variable']) ? $_GET['variable'] : "default_val";
  3.  
  4. // new way - null coalescing:
  5. $var = $_GET["variable"] ?? "default_val";

Both of the above lines do the same thing: they set $var to $_GET['variable'] if it is set (if it passes isset()), but if not then it sets $var to 'default_val'.

View More Details (and 4 discussions about this topic) Here...

How to reverse htmlentities() / What is the opposite of htmlentities()?

If you need to reverse or undo htmlentities() you can use the following function to do so in PHP:

  1. html_entity_decode($var)

This will convert HTML entities to their corresponding characters.

Info about html_entity_decode()

There are a few flags that you can use (as the 2nd parameter):

Constant NameDescription
ENT_COMPATWill convert double-quotes and leave single-quotes alone.
ENT_QUOTESWill convert both double and single quotes.
ENT_NOQUOTESWill leave both double and single quotes unconverted.
ENT_HTML401 Handle code as HTML 4.01.
ENT_XML1 Handle code as XML 1.
ENT_XHTML Handle code as XHTML.
ENT_HTML5 Handle code as HTML 5.

You can set what encoding to use by passing an option to the 3rd parameter. By default it will use the default_charset php setting.

The following character sets are supported:

CharsetAliasesDescription
ISO-8859-1ISO8859-1 Western European, Latin-1.
ISO-8859-5ISO8859-5 Little used cyrillic charset (Latin/Cyrillic).
ISO-8859-15ISO8859-15 Western European, Latin-9. Adds the Euro sign, French and Finnish letters missing in Latin-1 (ISO-8859-1).
UTF-8  ASCII compatible multi-byte 8-bit Unicode.
cp866ibm866, 866 DOS-specific Cyrillic charset.
cp1251Windows-1251, win-1251, 1251 Windows-specific Cyrillic charset.
cp1252Windows-1252, 1252 Windows specific charset for Western European.
KOI8-Rkoi8-ru, koi8r Russian.
BIG5950 Traditional Chinese, mainly used in Taiwan.
GB2312936 Simplified Chinese, national standard character set.
BIG5-HKSCS  Big5 with Hong Kong extensions, Traditional Chinese.
Shift_JISSJIS, SJIS-win, cp932, 932 Japanese
EUC-JPEUCJP, eucJP-win Japanese
MacRoman  Charset that was used by Mac OS.
''  An empty string activates detection from script encoding (Zend multibyte), default_charset and current locale (see nl_langinfo() and setlocale()), in this order. Not recommended.
View More Details (and 6 discussions about this topic) Here...

What does 'final class' and 'final function' (final method) mean in PHP?

If a class is defined as final class then no other class can extend it. I.e. the following would result in an error:

  1.         final class DontExtendMe {}
  2.         class ThisCausesAnError extends DontExtendMe {}

A final method (final function ...) means that any subclasses of it's class cannot be overridden.

View More Details (and 3 discussions about this topic) Here...

How do you launch the PHP interactive shell?

As of PHP 5.1.0, the CLI SAPI provides an interactive shell. To use it, enter the following command at a command line:

  1. php -a

If you run 'php -a' and just see 'Interactive mode enabled', but nothing happens when you type something and hit enter then this means that the interactive shell isn't activated for your installation of PHP. You must have the readline module installed (check if you do by running php -m | grep -i readline).

If you see 'Interactive mode enabled', then after typing in your PHP code (don't forget the opening PHP tag), press ctrl+d

$ php -a
Interactive mode enabled

<?php echo "hello, world" . rand(); ?>

hello, world665146942

Note: in the above output, I hit ctrl+d in the 2nd to last line, then it executed the PHP code that I typed and echoed the output.

View More Details (and 10 discussions about this topic) Here...

How to view all installed PHP modules?

It is very simple to see all installed PHP modules. Just run the following command:

php -m

For example, the output on one of my VM machines is:

$ php -m
[PHP Modules]
bcmath
bz2
calendar
Core
ctype
curl
date
dba
dom
exif
fileinfo
filter
ftp
gd
gettext
hash
iconv
imap
json
ldap
libxml
mbstring
mcrypt
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_pgsql
pdo_sqlite
Phar
posix
Reflection
session
shmop
SimpleXML
soap
sockets
SPL
sqlite3
standard
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
zip
zlib

[Zend Modules]
View More Details (and 9 discussions about this topic) Here...

How to find out which php.ini file PHP is using?

To find out which php.ini file (and its full file path) just run the following command:

php --ini

Which will output something like this:

$ php --ini
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         /etc/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

If you need to check from within a PHP script, you can either put this code in (if it isn't public facing) and search for 'Loaded configuration file':

  1. <?php phpinfo(); ?>

Or run:

  1. <?php var_dump(php_ini_loaded_file()); ?>

See also: php_ini_scanned_files()

View More Details (and 11 discussions about this topic) Here...

How do you run a PHP script from the command line?

Just run php your-file.php.

php your_file.php

And it will execute the PHP file.

View More Details (and 12 discussions about this topic) Here...

How to query mysql using PDO in PHP?

Years ago you used to see mysql_... functions everywhere. This has been (fortuantely) replaced by first the mysqli functions and more recently the object oriented way of PDO. Using PDO you can easily swap between database drivers (Mysql, Postgre, SQLite, etc). Here is how to connect to a mysql database, and then how to query it using PDO.

This also applies to mariadb

Connecting to MySQL with PDO in PHP

You should wrap this in a try/catch to handle a database connection error.

  1.   try {
  2.     $host = "your host";
  3.     $dbname = "your_database";
  4.     $user = "your_user";
  5.     $pass = "qwerrtyuiop12345678";
  6.  
  7.     $dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
  8.   }
  9.   catch(PDOException $e) {
  10.       echo  $e->getMessage(); // handle this better, this is just for the demo!
  11.   }

How to query the database

With PDO you don't have to think about escaping data. Every query should be 'prepared', then you can bind variables to placeholders. If you follow this example it should make sense.

In this example, we will do an insert and create a blog post with the following data:

  1. $title = "Blog post title";
  2. $post_body = "Blog post body";
  3. $status = "published_status";

Unnamed placeholders

  1.   $prepared_statement = $dbh->("INSERT INTO blog_posts (title, post_body, status) values (?, ?, ?)");

These are indexed, starting at 1.

  1. $prepared_statement->bindParam(1, $title);
  2. $prepared_statement->bindParam(2, $post_body);
  3. $prepared_statement->bindParam(3, $status);

And then you execute it:

  1. $prepared_statement->execute();

Named placeholders

You can also used named placeholders. They don't have to match anything else in the sql statement.

Although you will see a : before their names (such as :title) here and in most code, they aren't required. But they are a common convention that you should follow!

  1.   $prepared_statement = $dbh->("INSERT INTO blog_posts (title, post_body, status) values ( :title, :body, :post_status )");

Now that we have prepared the statement and used some named params, we need to bind them:

  1. $prepared_statement->bindParam(":title", $title);
  2. $prepared_statement->bindParam(":body", $post_body);
  3. $prepared_statement->bindParam(":post_status", $status);

And then you execute it:

  1. $prepared_statement->execute();

Alternative ways to do this:

You can also pass an array to ->execute with an array:

  1.   $prepared_statement = $dbh->("INSERT INTO blog_posts (title, post_body, status) values ( :title, :body, :post_status )");
  2.   $prepared_statement->execute([
  3.       "title" =>"my new blog post",
  4.       "body" => "Welcome to my new blog",
  5.       "post_status" => "published_status",
  6.   ]);
  7.   // or
  8.   $prepared_statement = $dbh->("INSERT INTO blog_posts (title, post_body, status) values ( ?,  ?, ? )");
  9.   $prepared_statement->execute([
  10.       "my new blog post",
  11.       "Welcome to my new blog",
  12.       "published_status",
  13.   ]);

An important thing to note about bindParam...

If you look at the method structure:

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )

You might notice the second parameter. It is &$variable - by reference. So if you did this:

  1.     $title = "title 1";
  2.   $prepared_statement = $dbh->("INSERT INTO blog_posts (title) values ( :title)");
  3.   $prepared_statement->bindParam(1, $title);
  4.   $title = "updated title here";
  5.   $prepared_statement->execute();?>

Then a new row would be inserted with "updated title here".

Why? because sent $title to bindParam, which saves the reference. You then update $title to "updated title here", so when you run ->execute() it uses whatever value is in $title, which is obviously the updated value.

Use bindValue() to avoid this issue.

How to get rows from the database?

By default PDO will return an array indexed by both column name and number (e.g. [1=> "some blog title", 'blog_title' => "some blog title", 2 => "some blog post body" , "post_body" => "some blog post body"].

There are a few ways to change this. You can use $statement->setFetchMode(...) (or $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);) to change this behaviour.

If I want to just work with an array I will normally use PDO::FETCH_ASSOC. The fetchObject method is nice too - it fetches the next row and returns it as an object. You can define what class it will create, so you can set it up to return model objects.

But anyway, on to some examples.

SELECT queries...

I am going to use the direct ->query() here, avoiding the binding and execute.

  1. $query = $dbh->query("SELECT * FROM blog_posts");
  2. foreach ($query as $row)
  3. {
  4.     var_dump($row);
  5. }

But I could also do this:

  1. $blog_post_id=123;
  2. $statement = $dbh->prepare("SELECT * FROM blog_posts WHERE id = ?");
  3. $statement->execute([ $blog_post_id] );
  4.  
  5. //get one row:
  6. $row = $statement->fetch();
  1. $category_id=22;
  2. $statement = $dbh->prepare("SELECT * FROM blog_posts WHERE category_id = ?");
  3. $statement->execute([ $category_id] );
  4.  
  5. // get all:
  6. $rows = $statement->fetchAll();

Update and delete

You can run these in a similar manner.

Delete SQL statement with PDO

  1. $category_id=22;
  2. $statement = $dbh->prepare("DELETE FROM blog_posts WHERE category_id = ?");
  3. $statement->execute([ $category_id] );

Update SQL statement with PDO

  1. $id=22;
  2. $new_title = "foobar";
  3. $statement = $dbh->prepare("UPDATE blog_posts set title = ? WHERE id = ?");
  4. $statement->execute([ $title, $id] );
View More Details (and 9 discussions about this topic) Here...

How could you include a custom function for every single time PHP runs?

There are probably a few ways to do this, but one simple way would be to put your function in a file in /somedir/something.php. Then update php.ini and set auto_prepend_file = /somedir/something.php.

If you want to use a package (via composer) on all of your scripts you could also do something like composer global require THEPACKAGE/NAMEHERE, then do auto_prepend_file = ${HOME}/.composer/vendor/autoload.php

I would not recommend doing this though! The setup will work only on your current machine, and would cause problems with debugging or getting your scripts to work the same on other machines. I have very rarely used auto_prepend_file, and every time I have it has caused problems with deployment to other servers or for testing.
View More Details (and 11 discussions about this topic) Here...

How to check if two strings are anagrams in PHP?

This is a classic simple programming question. There are several ways to approach this problem. Here is one solution:

The comparison function:

  1. function is_anagram($a, $b)
  2. {
  3.  
  4.     if (strlen($a) != strlen($b)) {
  5.         // if not same size then they definitely aren't
  6.         return false;
  7.     }
  8.  
  9. // turn 'foobar' into ['f', 'o', 'o', 'b', 'a', 'r']
  10. $a_chars = str_split($a);
  11. $b_chars = str_split($b);
  12.  
  13. // sort them...
  14. sort($a_chars);
  15. sort($b_chars);
  16.  
  17. // check if they're exactly the same...
  18. return $a_chars === $b_chars;
  19.  
  20. // another way to do this that someone emailed me about, which is much more simple:
  21. // return (count_chars($a, 1) == count_chars($b, 1))
  22.  
  23.  
  24. }

Let's write some tests

  1. $anagrams = [
  2.  
  3.     // $a, $b, $is_valid_anagram
  4.  
  5.         ["asdf", "asdf", true],
  6.         ["asdf", "fdsa", true],
  7.         ["asdfasdf", "asdfasdf", true],
  8.         ["a", "a", true],
  9.         ["a", "b", false],
  10.         ["aaa", "aaa", true],
  11.         ["aaa", "aa", false],
  12.         ["aaaa", "abab", false],
  13.         ["qwerty", "asdfg", false]
  14.  
  15. ];

And now let's go through each one.

  1. foreach ($anagrams as $anagram) {
  2.  
  3.     [$a, $b, $is_valid_anagram] = $anagram;
  4.  
  5.     $result = is_anagram($a, $b);
  6.     $result_message = $result ? "Is an anagram" : "Is not an anagram";
  7.  
  8.     if ($result != $is_valid_anagram) {
  9.         throw new \Exception("The anagram function returned an incorrect result for $a and $b");  // this doesn't happen with our function! :)
  10.     }
  11.     var_dump("[$a] and [$b] $result_message");
  12.  
  13. }
"Our function said that [asdf] and [asdf] Is an anagram, which is correct"
"Our function said that [asdf] and [fdsa] Is an anagram, which is correct"
"Our function said that [asdfasdf] and [asdfasdf] Is an anagram, which is correct"
"Our function said that [a] and [a] Is an anagram, which is correct"
"Our function said that [a] and [b] Is not an anagram, which is correct"
"Our function said that [aaa] and [aaa] Is an anagram, which is correct"
"Our function said that [aaa] and [aa] Is not an anagram, which is correct"
"Our function said that [aaaa] and [abab] Is not an anagram, which is correct"
"Our function said that [qwerty] and [asdfg] Is not an anagram, which is correct"

BTW, not sure about how the [$a, $b, $is_valid_anagram] = $anagram; line works? See my blog post about array destructuring in PHP 7.

View More Details (and 3 discussions about this topic) Here...