Press "Enter" to skip to content

Posts tagged as “php”

Full stack interview question lists

Database

What are the ACID properties in DBMS?

A transaction in a database system must maintain AtomicityConsistencyIsolation, and Durability − commonly known as ACID properties − in order to ensure accuracy, completeness, and data integrity.

  • Atomicity means that either rollback or commit the complete transaction.
  • Consistency is handled by MySQL’s logging mechanisms, which record all changes happening to your database and help us to ensure that no in-consistency will occur.
  • Isolation provides several low level locking which avoids (if properly handled) any other process to acquire lock on resource which is already in use by other process.
  • MySQL implements durability by maintaining a binary transaction log file that tracks changes to the system during the course of a transaction. In the event of a hardware failure or abrupt system shutdown, recovering lost data is a relatively straightforward task by using the last backup in combination with the log when the system restarts. By default, InnoDB tables are 100 percent durable (in other words, all transactions committed to the system before the crash are liable to be rolled back during the recovery process), while MyISAM tables offer partial durability.

What is transaction?

A transaction is a logical unit of work that contains one or more SQL statements. Transactions are atomic units of work that can be committed or rolled back. When a transaction makes multiple changes to the database, either all the changes succeed when the transaction is committed, or all the changes are undone when the transaction is rolled back.

When should you use transactions in my queries?

  • Use a transaction when you have a series of writes that need to be performed atomically; that is, they should all succeed or none should.
  • Needs the ability to rollback every change, if an error occurs or some other reason.

Transaction best practices

Using the SQL Server transaction helps maintaining the database integrity and consistency. On the other hand, a badly written transaction may affect the overall performance of your system by locking the database resources for long time. To overcome this issue, it is better to consider the following points when writing a transaction:

  • Narrow the scope of the transaction
  • Retrieve the data from the tables before opening the transaction if possible
  • Access the least amount of data inside the transaction body
  • Do not ask for user input inside the body of the transaction
  • Use a suitable mode of transactions
  • Use as suitable Isolation Level for the transaction

SQL

Difference between DELETE and TRUNCATE

DELETE is a DML(Data Manipulation Language) command and is used when we specify the row(tuple) that we want to remove or delete from the table or relation. The DELETE command can contain a WHERE clause. If WHERE clause is used with DELETE command then it remove or delete only those rows(tuple) that satisfy the condition otherwise by default it removes all the tuples(rows) from the table. 

TRUNCATE is a DDL(Data Definition Language) command and is used to delete all the rows or tuples from a table. Unlike the DELETE command, TRUNCATE command does not contain a WHERE clause. In the TRUNCATE command, the transaction log for each deleted data page is recorded. Unlike the DELETE command, the TRUNCATE command is fast. Like DELETE, we can rollback the data even after using the TRUNCATE command.

What is Pattern Matching in SQL?

  • Using the % wildcard to perform a simple search
    The % wildcard matches zero or more characters of any type and can be used to define wildcards both before and after the pattern. Search a student in your database with first name beginning with the letter K:
    • SELECT * FROM students WHERE first_name LIKE ‘K%’
  • Omitting the patterns using the NOT keyword
    Use the NOT keyword to select records that don’t match the pattern. This query returns all students whose first name does not begin with K.
    • SELECT * FROM students WHERE first_name NOT LIKE ‘K%’
  • Matching a pattern anywhere using the % wildcard twice
    Search for a student in the database where he/she has a K in his/her first name.
    • SELECT * FROM students WHERE first_name LIKE ‘%Q%’
  • Using the _ wildcard to match pattern at a specific position
    The _ wildcard matches exactly one character of any type. It can be used in conjunction with % wildcard. This query fetches all students with letter K at the third position in their first name.
    • SELECT * FROM students WHERE first_name LIKE ‘__K%’
  • Matching patterns for specific length
    The _ wildcard plays an important role as a limitation when it matches exactly one character. It limits the length and position of the matched results. For example –
    • SELECT * /* Matches first names with three or more letters */ FROM students WHERE first_name LIKE ‘___%’ SELECT * /* Matches first names with exactly four characters */ FROM students WHERE first_name LIKE ‘____’

How to create empty tables with the same structure as another table?

SELECT * INTO Students_copy FROM Students WHERE 1 = 2;

What is Normalization?

Normalization represents the way of organizing structured data in the database efficiently. It includes creation of tables, establishing relationships between them, and defining rules for those relationships. Inconsistency and redundancy can be kept in check based on these rules, hence, adding flexibility to the database.

What is Denormalization?

Denormalization is the inverse process of normalization, where the normalized schema is converted into a schema which has redundant information. The performance is improved by using redundancy and keeping the redundant data consistent. The reason for performing denormalization is the overheads produced in query processor by an over-normalized structure.

SQL Injection

SQL injection is a code injection technique that might destroy your database.

SQL Injection Based on 1=1 is Always True and Based on “”=”” is Always True

How to prevent SQL injection?

  1. Validate User Inputs and Sanitize Data
  2. Use Prepared Statements And Parameterization

HTML

Do your best to describe the process from the time you type in a website’s URL to it finishing loading on your screen? How is an HTML page rendered? What elements are created in what order?

Step 1 >> Get the ip address of the URL.
System checks the browser cache. Browser caches the DNS data for some time.
=> OS cache=>  DNS cache maintained by the router => next level where DNS cache of your ISP => DNS query to search for the required DNS data.

Step 2>> Once the browser gets the IP address it opens TCP connection and sends HTTP request to the web server.

Step 3>> The web server will handle the request [it happens in multiple steps] and send the HTTP response to the client/browser.

Step 4>> The browser parse the HTML document and render it.

Rendering steps:

  1. Start downloading external files (JavaScript, CSS, images) as they’re encountered in the HTML
  2. Parse external files once they are downloaded (or if they are inline and don’t require downloading)
  • if the files are scripts, then run them in the order they appear in the HTML
  • if they try to access the DOM right now, they will throw an error
  • while they run, they will prevent any other rendering, which is why some scripts are put at the bottom of the body
  • for CSS files, save the style rules in order they appear in the HTML
  • if they’re images then display them
  • if the loading fails, then proceed without this file
  1. End HTML Parsing
  2. Create the DOM – including all the styles we have so far
  3. Execute the DOMContentLoaded event when the DOM is fully constructed and scripts are loaded and run happens even if all other external files (images, css) are not done downloading (from step 4) in the Chrome F12 developer tools this is represented by a blue line on the Network view will start running anything you’ve added to this event, e.g. window.addEventListener(“DOMContentLoaded”, doStuff, true);
  4. Start painting the document to the display window (with any styles that have already loaded)
  5. Execute the window.onload event when all external files have loaded in the Chrome F12 developer tools this is represented by a red line on the Network view this will start running the jQuery ready function $(document).ready(function(){ … }); will start running any code you’ve added to this event, e.g. window.addEventListener(“load”, doStuff, true);
  6. Re-paint the document, including any new images and styles

CSS

Can you describe specificity in CSS?

  • Inline styles – An inline style is attached directly to the element to be styled. Example: <h1 style=”color: #ffffff;”>.
  • IDs – An ID is a unique identifier for the page elements, such as #navbar.
  • Classes, attributes and pseudo-classes – This category includes .classes, [attributes] and pseudo-classes such as :hover, :focus etc.
  • Elements and pseudo-elements  – This category includes element names and pseudo-elements, such as h1, div, :before and :after.

What are the values that you can position an element?

static, relative, absolute, fixed, sticky

Javascript

Can you explain closure in JS? 

Closure means that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned. Closures keep access to the variables they can be used to save state. And things that save state look a whole lot like objects

Difference between const, let, and var

var declarations are globally scoped or function scoped while let and const are block scoped. var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared. They are all hoisted to the top of their scope

What are the areas of scope in JS?

  • Global scope
  • Local scope / function scope
  • Block scope – introduced in ES6 that limits a variables scope to a given parenthesis block

What’s the difference between bind, apply and call?

The call, bind and apply methods can be used to set the this keyword independent of how a function is called. The bind method creates a copy of the function and sets the this keyword, while the call and apply methods sets the this keyword and calls the function immediately.

call requires the arguments to be passed in one-by-one, and apply takes the arguments as an array.

PHP

What is the difference between single-quoted and double-quoted strings in PHP?

  • Single quoted strings will display things almost completely “as is.” Variables and most escape sequences will not be interpreted. The exception is that to display a literal single quote, you can escape it with a back slash \', and to display a back slash, you can escape it with another backslash \\ (So yes, even single quoted strings are parsed).
  • Double quote strings will display a host of escaped characters (including some regexes), and variables in the strings will be evaluated. An important point here is that you can use curly braces to isolate the name of the variable you want evaluated. For example let’s say you have the variable $type and you want to echo "The $types are". That will look for the variable $types. To get around this use echo "The {$type}s are" You can put the left brace before or after the dollar sign. Take a look at string parsing to see how to use array variables and such.

How to check whether a variable is null in PHP?

Answer: Use the PHP is_null() function or === NULL

Concept

What is ORM?

ORM stands for Object-Relational Mapping (ORM) is a programming technique for converting data between relational databases and object oriented programming languages such as PHP, Java, C#, etc.

An ORM system has the following advantages:

  • Let’s business code access objects rather than DB tables.
  • Hides details of SQL queries from OO logic.
  • No need to deal with the database implementation.
  • Entities based on business concepts rather than database structure.
  • Transaction management and automatic key generation.
  • Fast development of application.

What is Dependency Injection?

Dependency Injection (DI) is a design pattern used to implement IoC. It allows the creation of dependent objects outside of a class and provides those objects to a class through different ways. Using DI, we move the creation and binding of the dependent objects outside of the class that depends on them.

What is Inversion of Control?

Inversion of control is a broad term but for a software developer it’s most commonly described as a pattern used for decoupling components and layers in the system. For example, creates a dependency between the TextEditor and the SpellChecker.

public class TextEditor {
  private SpellChecker checker;
  public TextEditor(SpellChecker checker) {    
    this.checker = checker;
  }
}

What is Bridge pattern?

Bridge pattern is used when we need to decouple an abstraction from its implementation so that the two can vary independently. This type of design pattern comes under structural pattern as this pattern decouples implementation class and abstract class by providing a bridge structure between them.

The bridge pattern is useful when both the class and what it does vary often. The class itself can be thought of as the abstraction and what the class can do as the implementation. The bridge pattern can also be thought of as two layers of abstraction.

Docker

Explain a use case for Docker

  • Docker is a low overhead way to run virtual machines on your local box or in the cloud. They’re not strictly distinct machines, they don’t need to boot an OS.
  • Docker can encapsulate legacy applications, allowing you to deploy them to servers that might not be easy to setup with older packages and software version.
  • Docker can be used to build test boxes, during your deploy process to facilitate continuous integration(CI) testing.
  • Docker can be used to provision boxes in the cloud, and with swarm you can orchestrate clusters too

API

Explain the main difference between REST and GraphQL

The main and most important difference between REST and GraphQL is that GraphQL is not dealing with dedicated resources, instead everything is regarded as a graph and therefore is connected and can be queried to app exact needs.

If you were to implement an API endpoint for checking if a resource exists, what path and method would you use?

RESTful path should only contain nouns–the method used on the endpoint should determine the action.

  • POST /users create a user model
  • PUT /users/{id|slug} replace a user model
  • PATCH /users/{id|slug} update part of a user model
  • DELETE /users/{id|slug} delete a user model
  • GET /users/{id|slug} retrieve a user model

The commonly accepted way to determine if a resource exists, using the above “user” resource as an example, then:

  • HEAD /users/{id|slug}

This request will use the least amount of bandwidth as it will return no data, simply just a 200 or 404 HTTP status.

A common issue when integrating third-party services within your own API requests is having to wait for the response, and as such, forcing the user to have to wait for a longer time. How would you do to avoid this?

The most effective way to solve this problem is to use queues. When a request is made to our API, a separate job is then created and added to a queue. This job will then be executed independently to the requested endpoint, thus allowing the server to respond without delay.

Message queue providers: Beanstalkd, RabbitMQ

How would you prevent a bot from scraping your publicly accessible API?

Technically, it is not possible to completely prevent data scraping. However, there is an effective solution that will deter most bots: rate limiting (throttling).

Throttling will prevent a certain device from making a defined number of requests within a defined time. Upon exceeding the defined number of requests, a 429 Too Many Attempts HTTP error should be thrown.

Note: It is important to track the device with more than just an IP address as this is not unique to the device and can result in an entire network losing access to an API.

Other less-than-ideal answers include:

  • Blocking requests based on the user agent string (easy to find a way around)
  • Generating temporary “session” access tokens for visitors at the front end.(this isn’t secure: storing a secret on the front end can be reverse-engineered, thus allowing anyone to generate access tokens)

If a user attempts to create a resource that already exists, what HTTP status code would you return?

Use a 409 conflict HTTP status code / 400 bad request

Node.js

What is Event Loop?

Node.js is a single threaded application but it support concurrency via concept of event and callbacks. As every API of Node js are asynchronous and being a single thread, it uses async function calls to maintain the concurrency. Node uses observer pattern. Node thread keeps an event loop and whenever any task get completed, it fires the corresponding event which signals the event listener function to get executed.

SEO

List some key things to consider when coding with SEO in mind

In order to build a site optimized for organic search engine rankings, it is important to implement certain standards throughout the code. These include:

  • Using the correct HTML tags for content hierachy i.e. <h1>/<h2>/<h3> and p
  • Use alt tag on images
  • Use vanity/friendly URLs (human readable)
  • Add XML sitemap
  • Add robots.txt file
  • Integrate Google analytics
  • Avoid broken links
  • Avoid Javascript errors
  • Avoid W3C markup validation errors
  • Minify your assets
  • Enable and force SSL
  • Include a meta description on each page
  • Specify relevant meta tags
  • Specify a favicon
  • Specify unique title for each page without exceeding 70 characters
  • Ensure there is enough content with enough relevant keywords
  • Leverage browser caching

List some ways you could optimize a website to be as efficient and scalable as possible.

  • Ensure no validation errors with W3C
  • Minified all your assets and all code
  • Place all assets on CDN
  • Reduce cookie size
  • Avoid inline Javascript and CSS
  • Leverage browser caching
  • Prefer async resources
  • Reduce DNS lookups
  • Avoid URL redirects
  • Avoid CSS @import
  • Serve scaled images, SVG
  • Avoid unnecessary images; where possible use CSS
  • Enable HTTP keep-alive
  • Minimize request size, avoid bad requests and 404s
  • Make fewer HTTP requests, load as few external resource as possible

To be continue….

Observer Design Pattern (PHP)

Observer is a behavioral design pattern that allows some objects to notify other objects about changes in their state.

PHP has several built-in interfaces (SplSubjectSplObserver) that can be used to make your implementations of the Observer pattern compatible with the rest of the PHP code.

Sample Code:

(Source from https://refactoring.guru/design-patterns/observer/php/example)

<?php

namespace RefactoringGuru\Observer\Conceptual;

/**
 * PHP has a couple of built-in interfaces related to the Observer pattern.
 *
 * Here's what the Subject interface looks like:
 *
 * @link http://php.net/manual/en/class.splsubject.php
 *
 *     interface SplSubject
 *     {
 *         // Attach an observer to the subject.
 *         public function attach(SplObserver $observer);
 *
 *         // Detach an observer from the subject.
 *         public function detach(SplObserver $observer);
 *
 *         // Notify all observers about an event.
 *         public function notify();
 *     }
 *
 * There's also a built-in interface for Observers:
 *
 * @link http://php.net/manual/en/class.splobserver.php
 *
 *     interface SplObserver
 *     {
 *         public function update(SplSubject $subject);
 *     }
 */

/**
 * The Subject owns some important state and notifies observers when the state
 * changes.
 */
class Subject implements \SplSubject
{
    /**
     * @var int For the sake of simplicity, the Subject's state, essential to
     * all subscribers, is stored in this variable.
     */
    public $state;

    /**
     * @var \SplObjectStorage List of subscribers. In real life, the list of
     * subscribers can be stored more comprehensively (categorized by event
     * type, etc.).
     */
    private $observers;

    public function __construct()
    {
        $this->observers = new \SplObjectStorage();
    }

    /**
     * The subscription management methods.
     */
    public function attach(\SplObserver $observer): void
    {
        echo "Subject: Attached an observer.\n";
        $this->observers->attach($observer);
    }

    public function detach(\SplObserver $observer): void
    {
        $this->observers->detach($observer);
        echo "Subject: Detached an observer.\n";
    }

    /**
     * Trigger an update in each subscriber.
     */
    public function notify(): void
    {
        echo "Subject: Notifying observers...\n";
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }

    /**
     * Usually, the subscription logic is only a fraction of what a Subject can
     * really do. Subjects commonly hold some important business logic, that
     * triggers a notification method whenever something important is about to
     * happen (or after it).
     */
    public function someBusinessLogic(): void
    {
        echo "\nSubject: I'm doing something important.\n";
        $this->state = rand(0, 10);

        echo "Subject: My state has just changed to: {$this->state}\n";
        $this->notify();
    }
}

/**
 * Concrete Observers react to the updates issued by the Subject they had been
 * attached to.
 */
class ConcreteObserverA implements \SplObserver
{
    public function update(\SplSubject $subject): void
    {
        if ($subject->state < 3) {
            echo "ConcreteObserverA: Reacted to the event.\n";
        }
    }
}

class ConcreteObserverB implements \SplObserver
{
    public function update(\SplSubject $subject): void
    {
        if ($subject->state == 0 || $subject->state >= 2) {
            echo "ConcreteObserverB: Reacted to the event.\n";
        }
    }
}

/**
 * The client code.
 */

$subject = new Subject();

$o1 = new ConcreteObserverA();
$subject->attach($o1);

$o2 = new ConcreteObserverB();
$subject->attach($o2);

$subject->someBusinessLogic();
$subject->someBusinessLogic();

$subject->detach($o2);

$subject->someBusinessLogic();

Output:

Subject: Attached an observer.
Subject: Attached an observer.

Subject: I'm doing something important.
Subject: My state has just changed to: 2
Subject: Notifying observers...
ConcreteObserverA: Reacted to the event.
ConcreteObserverB: Reacted to the event.

Subject: I'm doing something important.
Subject: My state has just changed to: 4
Subject: Notifying observers...
ConcreteObserverB: Reacted to the event.
Subject: Detached an observer.

Subject: I'm doing something important.
Subject: My state has just changed to: 1
Subject: Notifying observers...
ConcreteObserverA: Reacted to the event.

Adapter (PHP)

Adapter is a structural design pattern, which allows incompatible objects to collaborate. The Adapter acts as a wrapper between two objects. It catches calls for one object and transforms them to format and interface recognizable by the second object. It is often used to make existing classes work with others without modifying their source code

Use case: It’s very often used in systems based on some legacy code. In such cases, Adapters make legacy code work with modern classes.

Sample Code: (Source from https://refactoring.guru/design-patterns/adapter/php/example#example-1)

<?php

namespace RefactoringGuru\Adapter\RealWorld;

/**
 * The Target interface represents the interface that your application's classes
 * already follow.
 */
interface Notification
{
    public function send(string $title, string $message);
}

/**
 * Here's an example of the existing class that follows the Target interface.
 *
 * The truth is that many real apps may not have this interface clearly defined.
 * If you're in that boat, your best bet would be to extend the Adapter from one
 * of your application's existing classes. If that's awkward (for instance,
 * SlackNotification doesn't feel like a subclass of EmailNotification), then
 * extracting an interface should be your first step.
 */
class EmailNotification implements Notification
{
    private $adminEmail;

    public function __construct(string $adminEmail)
    {
        $this->adminEmail = $adminEmail;
    }

    public function send(string $title, string $message): void
    {
        mail($this->adminEmail, $title, $message);
        echo "Sent email with title '$title' to '{$this->adminEmail}' that says '$message'.";
    }
}

/**
 * The Adaptee is some useful class, incompatible with the Target interface. You
 * can't just go in and change the code of the class to follow the Target
 * interface, since the code might be provided by a 3rd-party library.
 */
class SlackApi
{
    private $login;
    private $apiKey;

    public function __construct(string $login, string $apiKey)
    {
        $this->login = $login;
        $this->apiKey = $apiKey;
    }

    public function logIn(): void
    {
        // Send authentication request to Slack web service.
        echo "Logged in to a slack account '{$this->login}'.\n";
    }

    public function sendMessage(string $chatId, string $message): void
    {
        // Send message post request to Slack web service.
        echo "Posted following message into the '$chatId' chat: '$message'.\n";
    }
}

/**
 * The Adapter is a class that links the Target interface and the Adaptee class.
 * In this case, it allows the application to send notifications using Slack
 * API.
 */
class SlackNotification implements Notification
{
    private $slack;
    private $chatId;

    public function __construct(SlackApi $slack, string $chatId)
    {
        $this->slack = $slack;
        $this->chatId = $chatId;
    }

    /**
     * An Adapter is not only capable of adapting interfaces, but it can also
     * convert incoming data to the format required by the Adaptee.
     */
    public function send(string $title, string $message): void
    {
        $slackMessage = "#" . $title . "# " . strip_tags($message);
        $this->slack->logIn();
        $this->slack->sendMessage($this->chatId, $slackMessage);
    }
}

/**
 * The client code can work with any class that follows the Target interface.
 */
function clientCode(Notification $notification)
{
    // ...

    echo $notification->send("Website is down!",
        "<strong style='color:red;font-size: 50px;'>Alert!</strong> " .
        "Our website is not responding. Call admins and bring it up!");

    // ...
}

echo "Client code is designed correctly and works with email notifications:\n";
$notification = new EmailNotification("developers@example.com");
clientCode($notification);
echo "\n\n";


echo "The same client code can work with other classes via adapter:\n";
$slackApi = new SlackApi("example.com", "XXXXXXXX");
$notification = new SlackNotification($slackApi, "Example.com Developers");
clientCode($notification);

Output:

Client code is designed correctly and works with email notifications:
Sent email with title 'Website is down!' to 'developers@example.com' that says '<strong style='color:red;font-size: 50px;'>Alert!</strong> Our website is not responding. Call admins and bring it up!'.

The same client code can work with other classes via adapter:
Logged in to a slack account 'example.com'.
Posted following message into the 'Example.com Developers' chat: '#Website is down!# Alert! Our website is not responding. Call admins and bring it up!'.

Singleton (PHP)

Singleton is a creational design pattern, which ensures that only that object exists in the memory and provides a single point of access to it for any other code.

<?php

namespace JSTechRoad\Singleton;

// The Singleton class defines the `GetInstance` method 
// that serves as an alternative to constructor and lets 
// clients access the same instance of this class forever.
class Singleton
{
    // The Singleton's instance is stored in a static field
    private static $instances = [];

    // The Singleton's constructor should always be private
    // to prevent direct construction calls with the `new` operator.
    protected function __construct() { }

    // Singletons should not be cloneable.
    protected function __clone() { }

    // Singletons should not be restorable from strings.
    public function __wakeup()
    {
        throw new \Exception("Cannot unserialize a singleton.");
    }

    // static method that controls the access to the singleton
    // instance. 
    public static function getInstance(): Singleton
    {
        $cls = static::class;
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static();
        }

        return self::$instances[$cls];
    }

    // any singleton should define some business logic, which can be
    // executed on its instance.
    public function someFunction()
    {
        // ...
    }
}

// testing function
function clientCode()
{
    $s1 = Singleton::getInstance();
    $s2 = Singleton::getInstance();
    if ($s1 === $s2) {
        echo "Singleton works!";
    } else {
        echo "Singleton failed!";
    }
}

clientCode();

Prototype (Clone) Design in PHP

Prototype (or Clone) is a creational design pattern that lets you copy existing objects not dependent on their classes. No need to go through all the fields of the original object and copy their values over to the new object. Simple as one word: CLONE!

<?php

namespace JSTechRoad\Prototype;

// PHP has built-in cloning support.
// Note that the constructor won't be executed during cloning.
// If you have complex logic inside the constructor,
// you may need to execute it in the `__clone` method as well.
class Prototype
{
    public $primitive;
    public $component;
    public $circularReference;

    public function __clone()
    {
        $this->component = clone $this->component;
        $this->circularReference = clone $this->circularReference;
        $this->circularReference->prototype = $this;
    }
}

class ComponentWithBackReference
{
    public $prototype;

    public function __construct(Prototype $prototype)
    {
        $this->prototype = $prototype;
    }
}

function clientCode()
{
    $p1 = new Prototype();
    $p1->primitive = 100;
    $p1->component = new \DateTime();
    $p1->circularReference = new ComponentWithBackReference($p1);

    $p2 = clone $p1;
    if ($p1->primitive === $p2->primitive) {
        echo "Primitive field values have been carried over to a clone.\n";
    } 
    if ($p1->component === $p2->component) {
        echo "Simple component has not been cloned.\n";
    }
    if ($p1->circularReference === $p2->circularReference) {
        echo "Component with back reference has not been cloned.\n";
    }

    if ($p1->circularReference->prototype === $p2->circularReference->prototype) {
        echo "Component with back reference is linked to original object.\n";
    }
}

clientCode();

 

 

Builder (PHP)

Builder is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code. The intent of the Builder design pattern is to separate the construction of a complex object from its representation.

Benefit:

  • You can construct objects step-by-step, defer construction steps or run steps recursively.
  • You can reuse the same construction code when building various representations of products. Single Responsibility Principle.
  • You can isolate complex construction code from the business logic of the product.

Disadvantage:

  • The overall complexity of the code increases since the pattern requires creating multiple new classes.

Why?

Imagine a complex object that requires different attributes, step-by-step initialization of many fields, and nested objects. Such initialization code usually comes with lots of parameters inside a constructor.

For example, a house is a complex object to implement, some houses have swimming pools, some houses have garages…etc. Let see the following approach:

  • we can create a big constructor in the base House class with all possible parameters that control the house object. But end up most of the parameters will be unused, making the constructor calls really ugly.
  • we have the base House class, extend the base House class and create a set of subclasses to cover all combinations of the parameters. But eventually, end up with a lot of subclasses.

Sample Code:

<?php

namespace JSTechRoad\Builder;

interface Builder
{
    public function producePartA(): void;

    public function producePartB(): void;

    public function producePartC(): void;
}

/**
 * implementations of the building steps.
 */
class ConcreteBuilder1 implements Builder
{
    private $product;

    /**
     * A new builder instance should contain a blank product object
     */
    public function __construct()
    {
        $this->reset();
    }

    public function reset(): void
    {
        $this->product = new Product1();
    }

    /**
     * All production steps work with the same product instance.
     */
    public function producePartA(): void
    {
        $this->product->parts[] = "PartA1";
    }

    public function producePartB(): void
    {
        $this->product->parts[] = "PartB1";
    }

    public function producePartC(): void
    {
        $this->product->parts[] = "PartC1";
    }

    public function getProduct(): Product1
    {
        $result = $this->product;
        $this->reset();

        return $result;
    }
}

/**
 * Use the Builder pattern only when your products are very
 * complex and require extensive configuration. 
 */
class Product1
{
    public $parts = [];

    public function listParts(): void
    {
        echo "Product parts: " . implode(', ', $this->parts) . "\n\n";
    }
}

/**
 * The Director is only responsible for executing the 
 * building steps in a particular sequence. It is helpful 
 * when producing products according to a
 * specific order or configuration. Strictly speaking,
 * the Director class is
 * optional, since the client can control builders directly.
 */
class Director
{
    private $builder;

    /**
     * The Director works with any builder instance 
     * that the client code passes to it.
     */
    public function setBuilder(Builder $builder): void
    {
        $this->builder = $builder;
    }

    /**
     * The Director can construct several product 
     * variations using the same building steps.
     */
    public function buildMinimalViableProduct(): void
    {
        $this->builder->producePartA();
    }

    public function buildFullFeaturedProduct(): void
    {
        $this->builder->producePartA();
        $this->builder->producePartB();
        $this->builder->producePartC();
    }
}

function clientCode(Director $director)
{
    $builder = new ConcreteBuilder1();
    $director->setBuilder($builder);

    echo "Standard basic product:\n";
    $director->buildMinimalViableProduct();
    $builder->getProduct()->listParts();

    echo "Standard full featured product:\n";
    $director->buildFullFeaturedProduct();
    $builder->getProduct()->listParts();

    // The Builder pattern can be used without a Director class.
    echo "Custom product:\n";
    $builder->producePartA();
    $builder->producePartC();
    $builder->getProduct()->listParts();
}

$director = new Director();
clientCode($director);

 

 

Abstract Factory (PHP)

Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.

Benefit:

  • You can be sure that the products you’re getting from a factory are compatible with each other.
  • You avoid tight coupling between concrete products and client code.
  • Single Responsibility Principle. You can extract the product creation code into one place, making the code easier to support.
  • Open/Closed Principle. You can introduce new variants of products without breaking existing client code.

Disadvantage:

  • The code may become more complicated since you need to introduce a lot of new subclasses to implement the pattern. The best case scenario is when you’re introducing the pattern into an existing hierarchy of creator classes.

Why?

For example. Our online furniture store has several variants of this family.

Products Chair + Sofa + Bed are available in these variants: Modern, Classic, Wooden.

A customer wants to order a Modern-style sofa. You need a way to create individual furniture objects so that they match other objects of the same family. You don’t want to change existing code when adding new products or families of products to the program. Furniture vendors update their catalogs very often, and you wouldn’t want to change the core code each time it happens.

Sample Code:

<?php

namespace JSTechRoad\AbstractFactory\Conceptual;

interface AbstractFactory
{
    public function createProductA(): AbstractProductA;

    public function createProductB(): AbstractProductB;
}

class ConcreteFactory1 implements AbstractFactory
{
    public function createProductA(): AbstractProductA
    {
        return new ConcreteProductA1();
    }

    public function createProductB(): AbstractProductB
    {
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 implements AbstractFactory
{
    public function createProductA(): AbstractProductA
    {
        return new ConcreteProductA2();
    }

    public function createProductB(): AbstractProductB
    {
        return new ConcreteProductB2();
    }
}

interface AbstractProductA
{
    public function usefulFunctionA(): string;
}

class ConcreteProductA1 implements AbstractProductA
{
    public function usefulFunctionA(): string
    {
        return "The result of the product A1.";
    }
}

class ConcreteProductA2 implements AbstractProductA
{
    public function usefulFunctionA(): string
    {
        return "The result of the product A2.";
    }
}

interface AbstractProductB
{
    /**
     * Product B is able to do its own thing...
     */
    public function usefulFunctionB(): string;

    /**
     * ...but it also can collaborate with the ProductA.
     *
     * The Abstract Factory makes sure that all products it creates are of the
     * same variant and thus, compatible.
     */
    public function anotherUsefulFunctionB(AbstractProductA $collaborator): string;
}

class ConcreteProductB1 implements AbstractProductB
{
    public function usefulFunctionB(): string
    {
        return "The result of the product B1.";
    }

    /**
     * The variant, Product B1, is only able to work correctly with the variant,
     * Product A1. Nevertheless, it accepts any instance of AbstractProductA as
     * an argument.
     */
    public function anotherUsefulFunctionB(AbstractProductA $collaborator): string
    {
        $result = $collaborator->usefulFunctionA();

        return "The result of the B1 collaborating with the ({$result})";
    }
}

class ConcreteProductB2 implements AbstractProductB
{
    public function usefulFunctionB(): string
    {
        return "The result of the product B2.";
    }

    /**
     * The variant, Product B2, is only able to work correctly with the variant,
     * Product A2. Nevertheless, it accepts any instance of AbstractProductA as
     * an argument.
     */
    public function anotherUsefulFunctionB(AbstractProductA $collaborator): string
    {
        $result = $collaborator->usefulFunctionA();

        return "The result of the B2 collaborating with the ({$result})";
    }
}


function clientCode(AbstractFactory $factory)
{
    $productA = $factory->createProductA();
    $productB = $factory->createProductB();

    echo $productB->usefulFunctionB() . "\n";
    echo $productB->anotherUsefulFunctionB($productA) . "\n";
}

// Testing
echo "Client: Testing client code with the first factory type:\n";
clientCode(new ConcreteFactory1());

echo "\n";

echo "Client: Testing the same client code with the second factory type:\n";
clientCode(new ConcreteFactory2());

 

 

Factory Method (PHP)

Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

Benefit:

  • You avoid tight coupling between the creator and the concrete products. Single Responsibility Principle.
  • You can move the product creation code into one place in the program, making the code easier to support. Open/Closed Principle.
  • You can introduce new types of products into the program without breaking existing client code.

Disadvantage:

  • The code may become more complicated since you need to introduce a lot of new subclasses to implement the pattern. The best case scenario is when you’re introducing the pattern into an existing hierarchy of creator classes.

Why?

Adding a new class to the program isn’t that simple if the rest of the code is already coupled to existing classes. For example, the original version of your app can only handle transportation by trucks, so the bulk of your code lives inside the Truck class.

After a while, your app becomes very popular. Suddenly, you receive dozens of requests from sea transportation companies to ask you to implement sea logistics into the app. (Ship class)

Sample code:

<?php

namespace RefactoringGuru\FactoryMethod\Conceptual;

abstract class Creator
{
    abstract public function factoryMethod(): Product;

    /**
     * Despite its name, the Creator's primary responsibility is
     * not creating products. Usually, it contains some core 
     * business logic that relies on Product objects,
     * returned by the factory method. Subclasses can
     * indirectly change that business logic by overriding
     * the factory method
     * and returning a different type of product from it.
     */
    public function someOperation(): string
    {
        // Call the factory method to create a Product object.
        $product = $this->factoryMethod();
        // Now, use the product.
        $result = "Creator: The same creator's code has just worked with " . $product->operation();

        return $result;
    }
}


class ConcreteCreator1 extends Creator
{
    public function factoryMethod(): Product
    {
        return new ConcreteProduct1();
    }
}

class ConcreteCreator2 extends Creator
{
    public function factoryMethod(): Product
    {
        return new ConcreteProduct2();
    }
}

/**
 * The Product interface declares the operations that all 
 * concrete products must implement.
 */
interface Product
{
    public function operation(): string;
}

/**
 * Concrete Products provide various implementations of the 
 * Product interface.
 */
class ConcreteProduct1 implements Product
{
    public function operation(): string
    {
        return "{Result of the ConcreteProduct1}";
    }
}

class ConcreteProduct2 implements Product
{
    public function operation(): string
    {
        return "{Result of the ConcreteProduct2}";
    }
}

/**
 * The client code works with an instance of a concrete 
 * creator, albeit through
 * its base interface. As long as the client keeps working 
 * with the creator via
 * the base interface, you can pass it any creator's subclass.
 */
function clientCode(Creator $creator)
{
    // ...
    echo "Client: I'm not aware of the creator's class, but it still works.\n" . $creator->someOperation();
    // ...
}

echo "App: Launched with the ConcreteCreator1.\n";
clientCode(new ConcreteCreator1());
echo "\n\n";

echo "App: Launched with the ConcreteCreator2.\n";
clientCode(new ConcreteCreator2());

 Output:

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}

PHP Cheat Sheet

Including PHP in a File

<?php

// place PHP code here

?>

Writing Comments

  • // — Denotes comments that only span one line
  • # — Another way of producing single-line comments
  • /*...*/ — Everything between /* and */ is not executed, also works across several lines

Outputting Data

In PHP, data is commonly output using echo or print. For example, the title of this blog post might be displayed on a page like this:

<?php
    echo "<h2>Hello World!</h2>";
?>

The two commands echo and print are pretty much the same. The only difference is that the former has no return value and can take several parameters, while the latter has a return value of 1 and can only take one argument.

Note: Like all other PHP commands, functions echo and print are not case sensitive. That means that when you write ECHOEcHoeCHO or any other variation, they will continue to work. As you will learn further on, that doesn’t apply to everything.

Writing PHP Functions

function NameOfTheFunction() {
    // PHP code here
}

Quick explanation: the first part is the function of a name (reminder: function names are not case sensitive). After that, everything between the curly braces is what the function does when called.

Defining Variables

In PHP, you denote a variable using the $ sign and assign its value using =. A typical example:

<?php
   $title = "PHP Cheat Sheet";
?>

Note:

  • Variables need to start with a letter or underscore (_) and can only be comprised of alpha-numeric characters
  • PHP variables are case sensitive, that means $myVar and $myvar are not the same thing
  • If your variable consists of more than one word you may write it $my_variable or $myVariable

Types of Data

  • Integers — Integers are non-decimal numbers between -2,147,483,648 and ,147,483,647. They must have at least one digit and no decimal point. It can be in decimal, hexadecimal, or octal.
  • Floats — This is the name for numbers with a decimal point or in exponential form.
  • Strings — This simply means text. We will talk about it in detail further below.
  • Boolean values — Meaning true/false statements.
  • Arrays — Arrays are variables that store several values. We will talk about them in detail further below.
  • Objects — Objects store both data and information on how to process it.
  • Resources — These are references to functions and resources outside of PHP.
  • NULL — A variable that is NULL doesn’t have any value.

There is no need to declare PHP variables in a certain way. They automatically take on the type of data they contain.

Variable Scope

Variables can be available in different scopes, meaning the part of a script you can access them. This can be globallocal and static.

Any variable declared outside of a function is available globally. That means it can be accessed outside of a function as well.

If you declare a variable inside a function, it will have a local scope. The consequence is that it can only be accessed within that function.

A way around this is to prepend a local variable with global. That way, it becomes part of the global scope:

function myFunction() {
    global $a, $b;
    $b = $a - $b;
}

In both cases, the variable becomes part of the $GLOBALS variable mentioned below.

Finally, it’s also possible to add static in front of a local variable. That way, it won’t be deleted after its function is executed and can be reused.

Predefined Variables

Reserve PHP variables, accessible from anywhere, regardless of scope.

  • $GLOBALS — Used to access global variables from anywhere inside a PHP script
  • $_SERVER — Contains information about the locations of headers, paths, and scripts
  • $_GET — Can collect data that was sent in the URL or submitted in an HTML form
  • $_POST — Used to gather data from an HTML form and to pass variables
  • $_REQUEST — Also collects data after submitting an HTML form

Variable-Handling Functions

There are a whole bunch of functions to work with variables:

  • boolval — Used to retrieve the boolean value of a variable
  • debug_zval_dump — Outputs a string representation of an internal zend value
  • empty — Checks whether a variable is empty or not
  • floatval — Get the float value of a variable (doubleval is another possibility)
  • get_defined_vars — Returns an array of all defined variables
  • get_resource_type — Returns the resource type
  • gettype — Retrieves the variable type
  • import_request_variables — Import GET/POST/Cookie variables into the global scope
  • intval — Find the integer value of a variable
  • is_array — Checks whether a variable is an array
  • is_bool — Finds out if a variable is a boolean
  • is_callable — Verify whether you can call the contents of a variable as a function
  • is_countable — Check whether the contents of a variable are countable
  • is_float — Find out if the type of a variable is float, alternatives: is_double and is_real
  • is_int — Check if the type of a variable is an integer, is_integer and is_long also works
  • is_iterable — Verify that a variable’s content is an iterable value
  • is_null — Checks whether a variable’s value is NULL
  • is_numeric — Find out if a variable is a number or a numeric string
  • is_object — Determines whether a variable is an object
  • is_resource — Check if a variable is a resource
  • is_scalar — Tests if a variable is a scalar
  • is_string — Find out whether the type of a variable is a string
  • isset — Determine if a variable has been set and is not NULL
  • print_r — Provides human-readable information about a variable
  • serialize — Generates a representation of a value that is storable
  • settype — Sets a variable’s type
  • strval — Retrieves the string value of a variable
  • unserialize — Creates a PHP value from a stored representation
  • unset — Unsets a variable
  • var_dump — Dumps information about a variable
  • var_export — Outputs or returns a string representation of a variable that can be parsed

Constants

Aside from variables, you can also define constants which also store values. In contrast to variables their value can not be changed, it’s locked in.

In PHP you can define a constant:

define(name, value, true/false)

The first is the name, the second the constant’s value and the third parameter whether its name should be case sensitive (the default is false).

Constants are useful since they allow you to change the value for an entire script in one place instead of having to replace every instance of it. They are also global in nature, meaning they can be accessed from anywhere.

Aside from user-defined constants, there also a number of default PHP constants:

  • __LINE__ — Denotes the number of the current line in a file
  • __FILE__ — Is the full path and filename of the file
  • __DIR__ — The directory of the file
  • __FUNCTION__ — Name of the function
  • __CLASS__ — Class name, includes the namespace it was declared in
  • __TRAIT__ — The trait name, also includes the namespace
  • __METHOD__ —  The class method name
  • __NAMESPACE__ — Name of the current namespace

PHP Arrays – Grouped Values

Arrays are a way to organize several values in a single variable so that they can be used together. While functions are for blocks of code, arrays are for the values – a placeholder for larger chunks of information.

In PHP there are different types of arrays:

  • Indexed arrays – Arrays that have a numeric index
  • Associative arrays – Arrays where the keys are named
  • Multidimensional arrays – Arrays that contain one or more other arrays

Declaring an Array in PHP

Arrays in PHP are created with the array()

<?php
  $cms = array("Banna", "Apple", "Pear");
  echo "What is your favorite fruit? Is it " . $cms[0] . ", " . $cms[1] . " or " . $cms[2] . "?";
?>

Array keys can either be strings or integers.

How to create an array with key value pairs in PHP?

PHP offers us a special type of array called an Associative Array that allows us to create an array with Key-Value pairs. The syntax for creating an Associative Array is as follows:

Syntax 1: Using array() constructor

$arrayVariable = array(
    key1 => value1,
    key2 => value2,
    key3 => value3,
    ...
    keyN => valueN,
);

Syntax 2: Using shorthand notation

$arrayVariable = [
    key1 => value1,
    key2 => value2,
    key3 => value3,
    ...
    keyN => valueN,
];

Array Functions

  • array_change_key_case — Changes all keys in an array to uppercase or lowercase
  • array_chunk — Splits an array into chunks
  • array_column — Retrieves the values from a single column in an array
  • array_combine — Merges the keys from one array and the values from another into a new array
  • array_count_values — Counts all values in an array
  • array_diff — Compares arrays, returns the difference (values only)
  • array_diff_assoc — Compares arrays, returns the difference (values and keys)
  • array_diff_key — Compares arrays, returns the difference (keys only)
  • array_diff_uassoc — Compares arrays (keys and values) through a user callback function
  • array_diff_ukey — Compares arrays (keys only) through a user callback function
  • array_fill — Fills an array with values
  • array_fill_keys — Fills an array with values, specifying keys
  • array_filter — Filters the elements of an array via a callback function
  • array_flip — Exchanges all keys in an array with their associated values
  • array_intersect — Compare arrays and return their matches (values only)
  • array_intersect_assoc — Compare arrays and return their matches (keys and values)
  • array_intersect_key — Compare arrays and return their matches (keys only)
  • array_intersect_uassoc — Compare arrays via a user-defined callback function (keys and values)
  • array_intersect_ukey — Compare arrays via a user-defined callback function (keys only)
  • array_key_exists — Checks if a specified key exists in an array, alternative: key_exists
  • array_keys — Returns all keys or a subset of keys in an array
  • array_map — Applies a callback to the elements of a given array
  • array_merge — Merge one or several arrays
  • array_merge_recursive — Merge one or more arrays recursively
  • array_multisort — Sorts of multiple or multi-dimensional arrays
  • array_pad — Inserts a specified number of items (with a specified value) into an array
  • array_pop — Deletes an element from the end of an array
  • array_product — Calculate the product of all values in an array
  • array_push — Push one or several elements to the end of the array
  • array_rand — Pick one or more random entries out of an array
  • array_reduce — Reduce the array to a single string using a user-defined function
  • array_replace — Replaces elements in the first array with values from following arrays
  • array_replace_recursive — Recursively replaces elements from later arrays into the first array
  • array_reverse — Returns an array in reverse order
  • array_search — Searches the array for a given value and returns the first key if successful
  • array_shift — Shifts an element from the beginning of an array
  • array_slice — Extracts a slice of an array
  • array_splice — Removes a portion of the array and replaces it
  • array_sum — Calculate the sum of the values in an array
  • array_udiff — Compare arrays and return the difference using a user function (values only)
  • array_udiff_assoc — Compare arrays and return the difference using default and a user function (keys and values)
  • array_udiff_uassoc — Compare arrays and return the difference using two user functions (values and keys)
  • array_uintersect — Compare arrays and return the matches via user function (values only)
  • array_uintersect_assoc — Compare arrays and return the matches via a default user function (keys and values)
  • array_uintersect_uassoc — Compare arrays and return the matches via two user functions (keys and values)
  • array_unique — Removes duplicate values from an array
  • array_unshift — Adds one or more elements to the beginning of an array
  • array_values — Returns all values of an array
  • array_walk — Applies a user function to every element in an array
  • array_walk_recursive — Recursively applies a user function to every element of an array
  • arsort — Sorts an associative array in descending order according to the value
  • asort — Sorts an associative array in ascending order according to the value
  • compact — Create an array containing variables and their values
  • count — Count all elements in an array, alternatively use sizeof
  • current — Returns the current element in an array, an alternative is pos
  • each — Return the current key and value pair from an array
  • end — Set the internal pointer to the last element of an array
  • extract — Import variables from an array into the current symbol table
  • in_array — Checks if a value exists in an array
  • key — Fetches a key from an array
  • krsort — Sorts an associative array by key in reverse order
  • ksort — Sorts an associative array by key
  • list — Assigns variables as if they were an array
  • natcasesort — Sorts an array using a “natural order” algorithm independent of case
  • natsort — Sorts an array using a “natural order” algorithm
  • next — Advance the internal pointer of an array
  • prev — Move the internal array pointer backward
  • range — Creates an array from a range of elements
  • reset — Set the internal array pointer to its first element
  • rsort — Sort an array in reverse order
  • shuffle — Shuffle an array
  • sort — Sorts an indexed array in ascending order
  • uasort — Sorts an array with a user-defined comparison function
  • uksort — Arrange an array by keys using a user-defined comparison function
  • usort — Categorize an array by values using a comparison function defined by the user

PHP Strings

In programming, speech strings are nothing more than text. As we have settled earlier, they are also a valid value for variables.

Defining Strings

In PHP there are several ways to define strings:

  • Single quotes — This is the simplest way. Just wrap your text in ' markers and PHP will handle it as a string.
  • Double quotes — As an alternative you can use ". When you do, it’s possible to use the escape characters below to display special characters.
  • heredoc — Begin a string with <<< and an identifier, then put the string in a new line. Close it in another line by repeating the identifier. heredoc behaves like double-quoted strings.
  • nowdoc — Is what heredoc is for double-quoted strings but for single quotes. It works the same way and eliminates the need for escape characters.

Note: Strings can contain variables, arrays, and objects.

Escape Characters

  • \n — Linefeed
  • \r — Carriage return
  • \t — Horizontal tab
  • \v — Vertical tab
  • \e — Escape
  • \f — Form feed
  • \\ — Backslash
  • \$ — Dollar sign
  • /' — Single quote
  • \" — Double quote
  • \[0-7]{1,3} — Character in octal notation
  • \x[0-9A-Fa-f]{1,2} — Character in hexadecimal notation
  • \u{[0-9A-Fa-f]+} — String as UTF-8 representation

String Functions

  • addcslashes() — Returns a string with backslashes in front of specified characters
  • addslashes() — Returns a string with backslashes in front of characters that need to be escaped
  • bin2hex() — Converts a string of ASCII characters to hexadecimal values
  • chop() — Removes space or other characters from the right end of a string
  • chr() — Returns a character from a specified ASCII value
  • chunk_split() — Splits a string into a series of smaller chunks
  • convert_cyr_string() — Converts a string from a Cyrillic character set to another
  • convert_uudecode() — Decodes a uuencoded string
  • convert_uuencode() — Encodes a string using uuencode
  • count_chars() — Returns information about the characters in a string
  • crc32() — Calculates a 32-bit CRC for a string
  • crypt() — Returns a hashed string
  • echo() or echo '' — Outputs one or several strings
  • explode() — Breaks down a string into an array
  • fprintf() — Writes a formatted string to a specified output stream
  • get_html_translation_table() — Returns the translation table used by htmlspecialchars() and htmlentities()
  • hebrev() — Transforms Hebrew text to visual text
  • hebrevc() — Converts Hebrew text to visual text and implements HTML line breaks
  • hex2bin() — Translate hexadecimal values to ASCII characters
  • html_entity_decode() — Turns HTML entities to characters
  • htmlentities() — Converts characters to HTML entities
  • htmlspecialchars_decode() — Transforms special HTML entities to characters
  • htmlspecialchars() — Switches predefined characters to HTML entities
  • implode() — Retrieves a string from the elements of an array, same as join()
  • lcfirst() — Changes a string’s first character to lowercase
  • levenshtein() — Calculates the Levenshtein distance between two strings
  • localeconv() — Returns information about numeric and monetary formatting for the locale
  • ltrim() — Removes spaces or other characters from the left side of a string
  • md5() — Calculates the MD5 hash of a string and returns it
  • md5_file() — Calculates the MD5 hash of a file
  • metaphone() — Provides the metaphone key of a string
  • money_format() — Returns a string as a currency string
  • nl_langinfo() — Gives specific locale information
  • nl2br() — Inserts HTML line breaks for each new line in a string
  • number_format() — Formats a number including grouped thousands
  • ord() — Returns the ASCII value of a string’s first character
  • parse_str() — Parses a string into variables
  • print() — Outputs one or several strings
  • printf() — Outputs a formatted string
  • quoted_printable_decode() — Converts a quoted-printable string to 8-bit binary
  • quoted_printable_encode() — Goes from 8-bit string to a quoted-printable string
  • quotemeta() — Returns a string with a backslash before metacharacters
  • rtrim() — Strips whitespace or other characters from the right side of a string
  • setlocale() — Sets locale information
  • sha1() — Calculates a string’s SHA-1 hash
  • sha1_file() — Does the same for a file
  • similar_text() — Determines the similarity between two strings
  • soundex() — Calculates the soundex key of a string
  • sprintf() — Returns a formatted string
  • sscanf() — Parses input from a string according to a specified format
  • str_getcsv() — Parses a CSV string into an array
  • str_ireplace() — Replaces specified characters in a string with specified replacements (case-insensitive)
  • str_pad() — Pads a string to a specified length
  • str_repeat() — Repeats a string a preset number of times
  • str_replace() — Replaces specified characters in a string (case-sensitive)
  • str_rot13() — Performs ROT13 encoding on a string
  • str_shuffle() — Randomly shuffles the characters in a string
  • str_split() — Splits strings into arrays
  • str_word_count() — Returns the number of words in a string
  • strcasecmp() — Case-insensitive comparison of two strings
  • strcmp() — Binary safe string comparison (case sensitive)
  • strcoll() — Compares two strings based on locale
  • strcspn() — Returns the number of characters found in a string before the occurrence of specified characters
  • strip_tags() — Removes HTML and PHP tags from a string
  • stripcslashes() — Opposite of addcslashes()
  • stripslashes() — Opposite of addslashes()
  • stripos() — Finds the position of the first occurrence of a substring within a string (case insensitive)
  • stristr() — Case-insensitive version of strstr()
  • strlen() — Returns the length of a string
  • strnatcasecmp() — Case-insensitive comparison of two strings using a “natural order” algorithm
  • strnatcmp() — Same as the aforementioned but case sensitive
  • strncasecmp() — String comparison of a defined number of characters (case insensitive)
  • strncmp() — Same as above but case-sensitive
  • strpbrk() — Searches a string for any number of characters
  • strpos() — Returns the position of the first occurrence of a substring in a string (case sensitive)
  • strrchr() — Finds the last occurrence of a string within another string
  • strrev() — Reverses a string
  • strripos() — Finds the position of the last occurrence of a string’s substring (case insensitive)
  • strrpos() — Same as strripos() but case sensitive
  • strspn() — The number of characters in a string with only characters from a specified list
  • strstr() — Case-sensitive search for the first occurrence of a string inside another string
  • strtok() — Splits a string into smaller chunks
  • strtolower() — Converts all characters in a string to lowercase
  • strtoupper() — Same but for uppercase letters
  • strtr() — Translates certain characters in a string, alternative: strchr()
  • substr() — Returns a specified part of a string
  • substr_compare() — Compares two strings from a specified start position up to a certain length, optionally case sensitive
  • substr_count() — Counts the number of times a substring occurs within a string
  • substr_replace() — Replaces a substring with something else
  • trim() — Removes space or other characters from both sides of a string
  • ucfirst() — Transforms the first character of a string to uppercase
  • ucwords() — Converts the first character of every word in a string to uppercase
  • vfprintf() — Writes a formatted string to a specified output stream
  • vprintf() — Outputs a formatted string
  • vsprintf() — Writes a formatted string to a variable
  • wordwrap() — Shortens a string to a given number of characters

PHP Operators

Operators allow you to perform operations with values, arrays, and variables. There are several different types.

Arithmetic Operators

Your standard mathematic operators.

  • + — Addition
  • - — Subtraction
  • * — Multiplication
  • / — Division
  • % — Modulo (the remainder of value divided by another)
  • ** — Exponentiation

Assignment Operators

Besides the standard assignment operator (=), you also have the following options:

  • += — a += b is the same as a = a + b
  • -= — a -= b is the same as a = a – b
  • *= — a *= b is the same as a = a * b
  • /= — a /= b is the same as a = a / b
  • %= — a %= b is the same as a = a % b

Comparison Operators

  • == — Equal
  • === — Identical
  • != — Not equal
  • <> — Not equal
  • !== — Not identical
  • < — Less than
  • > — Greater than
  • <= — Less than or equal to
  • >= — Greater than or equal to
  • <=> — Less than, equal to, or greater than

Logical Operators

  • and — And
  • or — Or
  • xor — Exclusive or
  • ! — Not
  • && — And
  • || — Or

Bitwise Operators

  • & — And
  • | — Or (inclusive or)
  • ^ — Xor (exclusive or)
  • ~ — Not
  • << — Shift left
  • >> — Shift right

Error Control Operator

You can use the @ sign to prevent expressions from generating error messages. This is often important for security reasons, for example, to keep confidential information safe.

Execution Operator

PHP supports one execution operator, which is `` (backticks). These are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command.

Increment/Decrement Operators

  • ++$i — Increments a variable by one, then returns it
  • $i++ — Returns a variable, then increments it by one
  • --$i — Decrements the variable by one, returns it afterward
  • $i-- — Returns the variable then decrements it by one

String Operators

  • . — Used to concatenate (mean combine) arguments
  • .= — Used to append the argument on the right to the left-side argument

Loops in PHP

Loops are very common in programming. They allow you to run through the same block of code under different circumstances. PHP has several different ones.

For Loop

This type goes through a block of code a specified number of times:

for ($i = 0; $i <= 10; $i++) {
    // code to execute goes here
}

Foreach Loop

A loop using foreach runs through each element in an array:

foreach ($InsertYourArrayName as $value) {
    // code to execute goes here
}
// or
foreach ($array as $key => $value)

While Loop

Loops through a block of code as long as a specified condition is true.

while (condition that must apply) {
    // code to execute goes here
}

Do…While Loop

The final PHP loop runs a code snippet once, then repeats the loop as long as the given condition is true.

do {
    // code to execute goes here;
} while (condition that must apply);

Conditional Statements

If/else statements are similar to loops. They are statements for running code only under certain circumstances. You have several options:

If/elseif/else Statement

if (condition) {
    // code to execute if condition is met
} elseif (condition) {
    // code to execute if this condition is met
} else {
    // code to execute if none of the conditions are met
}

Switch Statement

switch (n) {
    case 1:
        code to execute if n=1;
        break;
    case 'abc':
        code to execute if n='abc';
        break;
    case z:
        code to execute if n=z;
        break;
    // add more cases as needed
    default:
        code to execute if n is neither of the above;
}

Working with Forms in PHP

$_GET and $_POST help to collect data sent via a form.

Using GET vs POST

GET collects data via URL parameters. That means all variable names and their values are contained in the page address.

The advantage of this is that you’re able to bookmark the information. Keep in mind that it also means that the information is visible to everyone. For that reason, GET is not suitable for sensitive information such as passwords. It also limits the amount of data that can be sent in ca 2000 characters.

POST, on the other hand, uses the HTTP POST method to pass on variables. This makes the data invisible to third parties, as it is sent in the HTTP body. You are not able to bookmark it.

With POST, there are no limits to the amount of information you can send. Aside from that, it also has advanced functionality and is therefore preferred by developers.

Form Security

The most important issue when it comes to web forms is security. If not set up properly, they are vulnerable to cross-scripting attacks. The hackers add scripts to unsecured web forms to use them for their own purpose.

PHP offers following function to thwart those attacks:

  • htmlspecialchars()
  • trim()
  • stripslashes()

Required Fields, Error Messages and Data Validation

PHP is able to define required fields (you can’t submit the form without filling them out), display error messages if some information is missing and to validate data. We have already talked about the necessary tools to do so.

For example, you can simply define variables for your form fields and use the empty() function to check if they have values. After that, create a simple if/else statement to either send the submitted data or output an error message.

The next step is to check the submitted data for validity. For that, PHP offers a number of filters such as FILTER_VALIDATE_EMAIL to make sure a submitted email address has the right format.

Regular Exprressions (RegEx)

Syntax

$exp = "/w3schools/i";

RegEx Functions

preg_match()

Returns 1 if the pattern was found in the string and 0 if not

preg_match_all()

Returns the number of times the pattern was found in the string, which may also be 0

preg_replace()

Returns a new string where matched patterns have been replaced with another string

RegEx Modifiers

i Performs a case-insensitive search

m Performs a multiline search (patterns that search for the beginning or end of a string will match the beginning or end of each line)

u Enables correct matching of UTF-8 encoded patterns

RegEx Patterns

[abc] – Find one character from the options between the brackets

[^abc] – Find any character NOT between the brackets

[0-9] – Find one character from the range 0 to 9

Metacharacters

| Find a match for any one of the patterns separated by | as in: cat|dog|fish

. Find just one instance of any character

^ Finds a match as the beginning of a string as in: ^Hello

$ Finds a match at the end of the string as in: World$

\d Find a digit

\s Find a whitespace character

\b Find a match at the beginning of a word like this: \bWORD, or at the end of a word like this: WORD\b

\uxxxx Find the Unicode character specified by the hexadecimal number xxxx

Quantifiers

n+ Matches any string that contains at least one n

n* Matches any string that contains zero or more occurrences of n

n? Matches any string that contains zero or one occurrences of n

n{x} Matches any string that contains a sequence of X n’s

n{x,y} Matches any string that contains a sequence of X to Y n’s

n{x,} Matches any string that contains a sequence of at least X n’s

Grouping

Use parentheses ( ) to apply quantifiers to entire patterns. They cal also be used to select parts of the pattern to be used as a match.

<?php
  $str = "Apples and bananas.";
  $pattern = "/ba(na){2}/i";
  echo preg_match($pattern, $str); // Outputs 1
?>

PHP Functions

  • A function is a block of statements that can be used repeatedly in a program.
  • A function will not execute automatically when a page loads.
  • A function will be executed by a call to the function.

Default Argument Value

<?php declare(strict_types=1); // strict requirement
function setHeight(int $minheight = 100) {
  echo "The height is : $minheight <br>";
}
setHeight(50);
setHeight(); // will use the default value of 100

?>

PHP Filters

Filters are used to validate and filter data that is coming from insecure sources. As mentioned, a common example is user input. PHP offers a number of filter functions and constants for that:

Filter Functions

  • filter_has_var() — Checks if a variable of the specified type exists
  • filter_id() — Returns the ID belonging to a named filter
  • filter_input() — Retrieves a specified external variable by name and optionally filters it
  • filter_input_array() — Pulls external variables and optionally filters them
  • filter_list() — Returns a list of all supported filters
  • filter_var_array() — Gets multiple variables and optionally filters them
  • filter_var() — Filters a variable with a specified filter

Filter Constants

  • FILTER_VALIDATE_BOOLEAN — Validates a boolean
  • FILTER_VALIDATE_EMAIL — Certifies an e-mail address
  • FILTER_VALIDATE_FLOAT — Confirms a float
  • FILTER_VALIDATE_INT — Verifies an integer
  • FILTER_VALIDATE_IP — Validates an IP address
  • FILTER_VALIDATE_REGEXP — Confirms a regular expression
  • FILTER_VALIDATE_URL — Validates a URL
  • FILTER_SANITIZE_EMAIL — Removes all illegal characters from an e-mail address
  • FILTER_SANITIZE_ENCODED — Removes/Encodes special characters
  • FILTER_SANITIZE_MAGIC_QUOTES — Applies addslashes()
  • FILTER_SANITIZE_NUMBER_FLOAT — Removes all characters, except digits, +- and .,eE
  • FILTER_SANITIZE_NUMBER_INT — Gets rid of all characters except digits and + –
  • FILTER_SANITIZE_SPECIAL_CHARS — Removes special characters
  • FILTER_SANITIZE_FULL_SPECIAL_CHARS — Converts special characters to HTML entities
  • FILTER_SANITIZE_STRING — Removes tags/special characters from a string, alternative: FILTER_SANITIZE_STRIPPED
  • FILTER_SANITIZE_URL — Rids all illegal characters from a URL
  • FILTER_UNSAFE_RAW —Do nothing, optionally strip/encode special characters
  • FILTER_CALLBACK — Call a user-defined function to filter data

HTTP Functions in PHP

PHP also has the functionality to manipulate data sent to the browser from the webserver.

HTTP Functions

  • header() — Sends a raw HTTP header to the browser
  • headers_list() — A list of response headers ready to send (or already sent)
  • headers_sent() — Checks if and where the HTTP headers have been sent
  • setcookie() — Defines a cookie to be sent along with the rest of the HTTP headers
  • setrawcookie() — Defines a cookie (without URL encoding) to be sent along

Working with MySQL

Many platforms that are based on PHP work with a MySQL database in the background.

MySQL Functions

  • mysqli_affected_rows() — The number of affected rows in the previous MySQL operation
  • mysqli_autocommit() — Turn auto-committing database modifications on or off
  • mysqli_change_user() — Changes the user of the specified database connection
  • mysqli_character_set_name() — The default character set for the database connection
  • mysqli_close() — Closes an open database connection
  • mysqli_commit() — Commits the current transaction
  • mysqli_connect_errno() — The error code from the last connection error
  • mysqli_connect_error() — The error description from the last connection error
  • mysqli_connect() — Opens a new connection to the MySQL server
  • mysqli_data_seek() — Moves the result pointer to an arbitrary row in the result set
  • mysqli_debug() — Performs debugging operations
  • mysqli_dump_debug_info() — Dumps debugging information into a log
  • mysqli_errno() — The last error code for the most recent function call
  • mysqli_error_list() — A list of errors for the most recent function call
  • mysqli_error() — The last error description for the most recent function call
  • mysqli_fetch_all() — Fetches all result rows as an array
  • mysqli_fetch_array() — Fetches a result row as an associative, a numeric array, or both
  • mysqli_fetch_assoc() — Fetches a result row as an associative array
  • mysqli_fetch_field_direct() — Metadata for a single field as an object
  • mysqli_fetch_field() — The next field in the result set as an object
  • mysqli_fetch_fields() — An array of objects that represent the fields in a result set
  • mysqli_fetch_lengths() — The lengths of the columns of the current row in the result set
  • mysqli_fetch_object() — The current row of a result set as an object
  • mysqli_fetch_row() — Fetches one row from a result set and returns it as an enumerated array
  • mysqli_field_count() — The number of columns for the most recent query
  • mysqli_field_seek() — Sets the field cursor to the given field offset
  • mysqli_field_tell() — The position of the field cursor
  • mysqli_free_result() — Frees the memory associated with a result
  • mysqli_get_charset() — A character set object
  • mysqli_get_client_info() — The MySQL client library version
  • mysqli_get_client_stats() — Returns client per-process statistics
  • mysqli_get_client_version() — The MySQL client library version as an integer
  • mysqli_get_connection_stats() — Statistics about the client connection
  • mysqli_get_host_info() — The MySQL server hostname and the connection type
  • mysqli_get_proto_info() — The MySQL protocol version
  • mysqli_get_server_info() — Returns the MySQL server version
  • mysqli_get_server_version() — The MySQL server version as an integer
  • mysqli_info() — Returns information about the most recently executed query
  • mysqli_init() — Initializes MySQLi and returns a resource for use with mysqli_real_connect()
  • mysqli_insert_id() — Returns the auto-generated ID used in the last query
  • mysqli_kill() — Asks the server to kill a MySQL thread
  • mysqli_more_results() — Checks if there are more results from a multi-query
  • mysqli_multi_query() — Performs one or more queries on the database
  • mysqli_next_result() — Prepares the next result set from mysqli_multi_query()
  • mysqli_num_fields() — The number of fields in a result set
  • mysqli_num_rows() — The number of rows in a result set
  • mysqli_options() — Sets extra connect options and affect behavior for a connection
  • mysqli_ping() — Pings a server connection or tries to reconnect if it has gone down
  • mysqli_prepare() — Prepares an SQL statement for execution
  • mysqli_query() — Performs a query against the database
  • mysqli_real_connect() — Opens a new connection to the MySQL server
  • mysqli_real_escape_string() — Escapes special characters in a string for use in an SQL statement
  • mysqli_real_query() — Executes an SQL query
  • mysqli_reap_async_query() — Returns the result from async query
  • mysqli_refresh() — Refreshes tables or caches or resets the replication server information
  • mysqli_rollback() — Rolls back the current transaction for the database
  • mysqli_select_db() — Changes the default database for the connection
  • mysqli_set_charset() — Sets the default client character set
  • mysqli_set_local_infile_default() — Unsets a user-defined handler for the LOAD LOCAL INFILE command
  • mysqli_set_local_infile_handler() — Sets a callback function for the LOAD DATA LOCAL INFILE command
  • mysqli_sqlstate() — Returns the SQLSTATE error code for the last MySQL operation
  • mysqli_ssl_set() — Establishes secure connections using SSL
  • mysqli_stat() — The current system status
  • mysqli_stmt_init() — Initializes a statement and returns an object for use with mysqli_stmt_prepare()
  • mysqli_store_result() — Transfers a result set from the last query
  • mysqli_thread_id() — The thread ID for the current connection
  • mysqli_thread_safe() — Returns if the client library is compiled as thread-safe
  • mysqli_use_result() — Initiates the retrieval of a result set from the last query executed using the mysqli_real_query()
  • mysqli_warning_count() — The number of warnings from the last query in the connection

Date/Time Functions

  • checkdate() — Checks the validity of a Gregorian date
  • date_add() — Adds a number of days, months, years, hours, minutes and seconds to a date object
  • date_create_from_format() — Returns a formatted DateTime object
  • date_create() — Creates a new DateTime object
  • date_date_set() — Sets a new date
  • date_default_timezone_get() — Returns the default timezone used by all functions
  • date_default_timezone_set() — Sets the default timezone
  • date_diff() — Calculates the difference between two dates
  • date_format() — Returns a date formatted according to a specific format
  • date_get_last_errors() — Returns warnings or errors found in a date string
  • date_interval_create_from_date_string() — Sets up a DateInterval from relative parts of a string
  • date_interval_format() — Formats an interval
  • date_isodate_set() — Sets a date according to ISO 8601 standards
  • date_modify() — Modifies the timestamp
  • date_offset_get() — Returns the offset of the timezone
  • date_parse_from_format() — Returns an array with detailed information about a specified date, according to a specified format
  • date_parse() — Returns an array with detailed information about a specified date
  • date_sub() — Subtracts days, months, years, hours, minutes and seconds from a date
  • date_sun_info() — Returns an array containing information about sunset/sunrise and twilight begin/end for a specified day and location
  • date_sunrise() — The sunrise time for a specified day and location
  • date_sunset() — The sunset time for a specified day and location
  • date_time_set() — Sets the time
  • date_timestamp_get() — Returns the Unix timestamp
  • date_timestamp_set() — Sets the date and time based on a Unix timestamp
  • date_timezone_get() — Returns the time zone of a given DateTime object
  • date_timezone_set() — Sets the time zone for a DateTime object
  • date() — Formats a local date and time
  • getdate() — Date/time information of a timestamp or the current local date/time
  • gettimeofday() — The current time
  • gmdate() — Formats a GMT/UTC date and time
  • gmmktime() — The Unix timestamp for a GMT date
  • gmstrftime() — Formats a GMT/UTC date and time according to locale settings
  • idate() — Formats a local time/date as an integer
  • localtime() — The local time
  • microtime() — The current Unix timestamp with microseconds
  • mktime() — The Unix timestamp for a date
  • strftime() — Formats a local time and/or date according to locale settings
  • strptime() — Parses a time/date generated with strftime()
  • strtotime() — Transforms an English textual DateTime into a Unix timestamp
  • time() — The current time as a Unix timestamp
  • timezone_abbreviations_list() — Returns an array containing dst, offset, and the timezone name
  • timezone_identifiers_list() — An indexed array with all timezone identifiers
  • timezone_location_get() — Location information for a specified timezone
  • timezone_name_from_abbr() — Returns the timezone name from an abbreviation
  • timezone_name_get() — The name of the timezone
  • timezone_offset_get() — The timezone offset from GMT
  • timezone_open() — Creates a new DateTimeZone object
  • timezone_transitions_get() — Returns all transitions for the timezone
  • timezone_version_get() — Returns the version of the timezonedb

Date and Time Formatting

  • d — 01 to 31
  • j — 1 to 31
  • D — Mon through Sun
  • l — Sunday through Saturday
  • N — 1 (for Mon) through 7 (for Sat)
  • w — 0 (for Sun) through 6 (for Sat)
  • m — Months, 01 through 12
  • n — Months, 1 through 12
  • F — January through December
  • M — Jan through Dec
  • Y — Four digits year (e.g. 2018)
  • y — Two digits year (e.g. 18)
  • L — Defines whether it’s a leap year (1 or 0)
  • a — am and pm
  • A — AM and PM
  • g — Hours 1 through 12
  • h — Hours 01 through 12
  • G — Hours 0 through 23
  • H — Hours 00 through 23
  • i — Minutes 00 to 59
  • s — Seconds 00 to 59

PHP Errors

Error Functions

  • debug_backtrace() — Used to generate a backtrace
  • debug_print_backtrace() — Prints a backtrace
  • error_get_last() — Gets the last error that occurred
  • error_log() — Sends an error message to the web server’s log, a file or a mail account
  • error_reporting() — Specifies which PHP errors are reported
  • restore_error_handler() — Reverts to the previous error handler function
  • restore_exception_handler() — Goes back to the previous exception handler
  • set_error_handler() — Sets a user-defined function to handle script errors
  • set_exception_handler() — Sets an exception handler function defined by the user
  • trigger_error() — Generates a user-level error message, you can also use user_error()

Error Constants

  • E_ERROR — Fatal run-time errors that cause the halting of the script and can’t be recovered from
  • E_WARNING — Non-fatal run-time errors, execution of the script continues
  • E_PARSE — Compile-time parse errors, should only be generated by the parser
  • E_NOTICE — Run-time notices that indicate a possible error
  • E_CORE_ERROR — Fatal errors at PHP initialization, like an E_ERROR in PHP core
  • E_CORE_WARNING — Non-fatal errors at PHP startup, similar to E_WARNING but in PHP core
  • E_COMPILE_ERROR — Fatal compile-time errors generated by the Zend Scripting Engine
  • E_COMPILE_WARNING — Non-fatal compile-time errors by the Zend Scripting Engine
  • E_USER_ERROR — Fatal user-generated error, set by the programmer using trigger_error()
  • E_USER_WARNING — Non-fatal user-generated warning
  • E_USER_NOTICE — User-generated notice by trigger_error()
  • E_STRICT — Suggestions by PHP to improve your code (needs to be enabled)
  • E_RECOVERABLE_ERROR — Catchable fatal error caught by a user-defined handle
  •  E_DEPRECATED — Enable this to receive warnings about a code which is not future-proof
  • E_USER_DEPRECATED — User-generated warning for deprecated code
  • E_ALL — All errors and warnings except E_STRICT

PHP Object Oriented Programming Quick Reference Guide

Source from https://www.logicbig.com/

Features/SyntaxDescription/examples

class

A class is a blueprint from which we create object instances. A class mainly contains properties and methods.

Variables and functions are called properties and methods respectively in OOP world.

‘new’ keyword

To create an instance of a class, new keyword is used new MyClass();

pseudo-variable $this

The reference to the current object, only used within the class.

Object operator ->

Used when calling a method or accessing a property on an object instance. It is used with $this as well.

<?php
class MyClass {
   // defining a property
   public $myProperty = 'a property value';

   // defining a method
   public function display() {
     echo $this->myProperty;
   }
}

$var = new MyClass();
$var->display();
?>
  
Output:
a property value

Visibility

The visibility keywords (public, protected, private) determines how an object properties/methods are accessible:

  • public: can be accessed anywhere.
  • protected: can be accessed by the class and subclasses only.
  • private: can be accessed by the class only.

A property must be defined with one of the above visibility keywords.

A method defined without any of them will have public visibility by default.

<?php
class MyClass {
  public $var1 = 'public var';
  protected $var2 = 'protected var';
  private $var3 = 'private var';

  function printHello() {
    echo $this->var1 . '<br>';
    echo $this->var2 . '<br>';
    echo $this->var3 . '<br>';
  }
}

$obj = new MyClass();
echo $obj->var1 . '<br>'; // prints public var
$obj->printHello(); // prints all

// if uncommented followings will produce fatal errors
/*
* echo $obj->var2; // Fatal Error
* echo $obj->var3; // Fatal Error
*/
Output:
public var
public var
protected var
private var

Class constants

Just like defining other constants (outside of a class) using ‘const’ keyword, we can also define them inside a class. The default visibility of class constants is public.

Constants are allocated once per class, and not for each class instance.

Scope Resolution Operator (::)

Instead of using ->, double colon allows access to static and constant. This operator is also used to access super class features.

Using ‘self’

Instead of using $this, the self keyword is used to access constants within the class. Generally, for all class level access self should be used and for all current object instance access $this should be used within the class.
<?php
class MyClass {
   const PI = 3.14159;

  function showPI() {
       echo self::PI . "<br>";
  }
}

echo MyClass::PI . "<br>";
$class = new MyClass();
$class->showPI();
echo $class::PI . "<br>";
?>
Output:
3.14159
3.14159
3.14159

static properties and methods

Class properties and methods can be declared with static keyword which makes them class level features and we don’t need a class instance to access those features.

Like class constants we access static properties/methods with double colon (::) and to access them within class we use self keyword.

$this is not available inside a static method.

By default static features have ‘public’ accessibility.

For static variable initialization, the same rules apply as const expressions.

<?php
class MyClass {
  static $var = 'a static property';

  static function aMethod() {
    return self::$var;
  }
}

echo MyClass::$var . '<br>';
echo MyClass::aMethod();
?>
Output:
a static property
a static property

Constructors and destructors

A constructor function __construct() is a special (magic) function which is automatically called when an object instance is created with ‘new’ keyword. A constructor can have any number of user defined parameters. Constructors should ideally be used to initialize object

A destructor is a special function __destruct() which is automatically called when object is deleted from memory by garbage collector.

Objects are deleted as soon as no references of them used in the program, or during the shutdown sequence.

Destructors are typically used for cleanup, state persistence, etc.

 <?php
class MyClass {
   private $prop;

   function __construct($var) {
     echo 'In constructor of ' . __CLASS__ . '<br>';
     $this->prop = $var;
   }

   public function displayProp() {
     echo $this->prop .'<br>';
   }

   function __destruct() {
     echo 'destroying ' . __CLASS__;
   }
}

$a = new MyClass('the property value');
$a->displayProp();
?>
Output
In constructor of MyClass
the property value
destroying MyClass

Inheritance:

Inheritance is the process of extending an existing class (parent class) by a new class (subclass) using extends keywords.

A subclass inherits all properties and methods from it’s super (parent) class except for private ones.

Inheritance is used for code reuse and polymorphism.

PHP allows single inheritance (at most one super class)

<?php
class MyParentClass {
  protected $var = 'a super call property';

  public function display() {
     echo $this->var . '<br>';
  }
}
class MySubclass extends MyParentClass {
  public function getVar() {
     return 'returning ' . $this->var;
  }
}

$a = new MySubClass();
$a->display();
echo $a->getVar();
?>
Output:
a super call property
returning a super call property

Inheritance and Construct/destruct

Parent class constructor/destructor are not implicitly called if the child class defines them as well. In order to run a parent constructor (or destructor), a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method.

parent keyword

Similar to ‘self’ keyword which is used to access class level static and constant features, parent is used to access super class level features from subclass that includes construct/destruct and overridden methods (next topic).

<?php
class A {
   protected static $x = 'value x';
   function __construct() {
     echo 'In constructor of ' . __CLASS__ . '<br>';
   }
}
class B extends A {
   function __construct() {
     parent::__construct();
     echo parent::$x .'<br>';
     echo 'In constructor of ' . __CLASS__ . '<br>';
   }
}

$b = new B();
  
Output:
In constructor of A
value x
In constructor of B

Method overriding

Method overriding is the process where a subclass redefine a parent class method to change it’s behavior. The signature should exactly be the same.


In case if we want to access parent level features from within a subclass then we will use parent::

<?php
class A {
  function aMethod() {
    return "aMethod from A";
  }
}

class B extends A {
  function aMethod() {
       return "aMethod from B, ".
       parent::aMethod();
  }
}

$a = new A;
echo($a->aMethod());
echo('<br>');
$b = new B;
echo($b->aMethod());
?>
Output
aMethod from A
aMethod from B, aMethod from A

Abstract classes

An abstract class cannot be instantiated. They provide base class abstract implementation to be extended to provide some specific behavior.

An abstract thing doesn’t exist in reality e.g. an animal doesn’t exists as a concrete thing but an specialization e.g. dog does exist.

An abstract class definition starts with abstract keyword.

An abstract class can defined method(s) without body. In that case, we have to use abstract keyword in the method signature.

A subclass must override abstract methods or otherwise should be ‘abstract’ themselves.

<?php
abstract class A{
  abstract protected function aMethod();

  public function doSomething(){
    $this->aMethod();
  }
}
class B extends A{
  protected function aMethod(){
    echo 'aMethod called';
  }
}

$b = new B();
$b->doSomething();
Output:
aMethod called

Interfaces

Like an abstract class, Interface is another way to define abstract type.

Interfaces define methods without implementation. They don’t have to use abstract keyword.

To define an interface we use interface keyword instead of class.

All methods in an interface should be public.

Class implementing interfaces

A class may implement one or more comma separated interfaces by using implements keyword. The class must implement all interface methods or otherwise should be declared abstract.


Interfaces can extend each other by using keyword extends

<?php
interface Task {
  public function runTask();
  public function anotherMethod();
}

abstract class TaskImpl implements Task {
  public function runTask() {
    echo $this->anotherMethod();
  }
}

class TaskImpl2 extends TaskImpl {
  public function anotherMethod() {
    return "another method running task ";
  }
}

$task = new TaskImpl2();
$task->runTask();
?>
Output:
another method running task

Traits

A Trait is intended to reduce some limitations of PHP single inheritance model. A developer can reuse sets of methods freely in several independent classes living in different class hierarchies..

  1. A trait is defined using keyword trait. It is similar to a class, but cannot be instantiated it’s own.
    trait MyTrait {
    ...
    }
  2. A trait can have properties and magic methods. It can also have static properties and methods.
  3. To use them in a class use keyword use followed by the trait name. A class can have multiple comma separated traits.
    class MyClass{
     use MyTrait1, MyTrait2;
     ...
    }
  4. In case of conflicts, the class overrides trait functions, but if those functions are defined in a parent class of the current class then traits overrides them.
  5. If two traits have a method with the same name, a fatal error is produced. We can resolve the conflict by using insteadof operator:
    class MyClass{
     user MyTrait1, MyTrait2{
      MyTrait2::aMethod insteadof MyTrait1;
     }
      ...
    }
  6. Since insteadof operator excludes one of the method, we can re-include the excluded method by using as operator which gives an alias to the method.
    class MyClass{
      use MyTrait1, MyTrait2{
       MyTrait2::aMethod insteadof MyTrait1;
       MyTrait1::aMethod as otherMethod;
      }
    }
    $a = new MyClass();
    $a->aMethod();//calls MyTrait2::aMethod
    $a->otherMethod();//calls MyTrait1::aMethod
  7. We can also change the visibility of a method using as operator:
    class MyClass{
     use MyTrait {
     aMethod as private aPrivateMethod;
     }
    }
  8. A trait can use other traits too:
    trait MyTrait{
     use MyOtherTrait;
    }
  9. A trait can have abstract methods too. In that case classes using them have to implement the method.
<?php
trait  ATrait{
  private $var;

  function __construct($str) {
   $this->var = $str;
  }

  public function aTraitFunction() {
   echo __METHOD__ . ", from ATrait:  $this->var<br>";
  }

  public function aTraitFunction2() {
   echo __METHOD__ . ", from ATrait:  $this->var<br>";
  }

  function __toString() {
   return __CLASS__ . ", var=$this->var <br>";
  }
}

trait BTrait{
  public function aTraitFunction2() {
   echo __METHOD__ . ", from BTrait:  $this->var<br>";
  }
}

class BClass {
  public function aTraitFunction2() {
   echo __METHOD__ . ", from BClass:  $this->var<br>";
  }
}

class AClass extends BClass {
  use ATrait, BTrait{
   BTrait::aTraitFunction2 insteadof ATrait;
  }

  public function aTraitFunction() {
   echo __METHOD__ . ", frome AClass: $this->var<br>";
  }
}

$a = new AClass('a string');
echo $a;
$a->aTraitFunction();
$a->aTraitFunction2();
Output:
AClass, var=a string
AClass::aTraitFunction, frome AClass: a string
BTrait::aTraitFunction2, from BTrait: a string

Final keyword

A method declared with final keyword cannot be overridden by a subclass.

A class declared with final keyword cannot be extended.

class A {
  final function display() {
   echo "displaying in " . __CLASS__;
  }
}
class B extends A {
  function display() {
   echo "displaying in " . __CLASS__;
  }
}

$b = new B();
$b->display();
Output:
Fatal error: Cannot override final method A::display() in D:\eclipse-workspace\php-oop\final.php on line 13
final class A {
}
class B extends A {
}

$b = new B();
Output:
Fatal error: Class B may not inherit from final class (A) in D:\eclipse-workspace\php-oop\final-class.php on line 5

Objects equality

  • The comparison operator == compares the objects by their property values and by types. Two objects are equal if they are instances of the same class and have same property values and, even though they are different references.
  • The identity operator === compares the object by their references. The object variables are identical if and only if they refer to the same instance of the same class.
<?php
class MyClass {
}

function toString($bool) {
  if ($bool === false) {
   return 'FALSE';
  } else {
   return 'TRUE';
  }
}

$a = new MyClass();
$b = new MyClass();
$c = $a;

echo '<br>$a==$b : ' . toString($a == $b);
echo '<br>$a===$b : ' . toString($a === $b);
echo '<br>$a==$c : ' . toString($a == $c);
echo '<br>$a===$c : ' . toString($a === $c);
  
Output:
$a==$b : TRUE
$a===$b : FALSE
$a==$c : TRUE
$a===$c : TRUE

Object iteration

By default all visible properties can be iterated using foreach loop.

To control iteration process we can implement built-in Iterator interface.

<?php
class TestClass {
  public $str = 'a str property';
  public $int = 3;
  protected $str2 = "a protected str property";
  private $str3 = "a private str property";

  function display(){
    foreach($this as $key => $value){
      echo "$key => $value <br>";
    }
  }
}

$a = new TestClass();
$a->display();
echo '----<br>';
foreach($a as $key => $value){
	echo "$key => $value <br>";
}
Output:
str => a str property
int => 3
str2 => a protected str property
str3 => a private str property
----
str => a str property
int => 3

Auto-loading Classes

For a typical PHP application, a developer has to use multiple include statements to include multiple files. Per good practice, there should be a single class in a file.

spl_autoload_register function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.

Assume class A resides in A.php and class B resides in B.php at the same location as this Test.php script:

<?php
spl_autoload_register(function ($className) {
 	echo "including $className.php <br>";
	 include $className . '.php';
});

$a = new A();
$b = new B();
 
including A.php
including B.php

Magic methods

These special methods get called in response to a particular event or scenario. We just have to implement them in our class. These methods starts with double underscores. We have seen two magic methods above already: __construct() and __destruct().

Here’s the complete list: __construct(), __destruct()__toString(), __set(), __get(), __isset(), __unset(), __call(), __callStatic() __invoke(), __set_state(), __clone(), __sleep(), __wakeup(), and __debugInfo()

we are going to explore them in the following sections.

String representation of objects

__toString()

This method should return a string. It’s a way to represent an object as a string.

<?php
class MyClass{

  private $var = 'a property';

  public function __toString(){
    return "MyClass: var = '$this->var'";
  }
}

$a = new MyClass();
echo $a;
  
Output:
MyClass: var = 'a property'

Property Overloading

__set(), __get(), __isset(), __unset()

This is a way to dynamically create object properties which do not exist or are inaccessible.

  • __set(): is triggered when an inaccessible property is assigned a value.
  • __get(): is triggered when an inaccessible property is accessed.
  • __isset(): is triggered when calling built-in functions isset() or empty() on inaccessible properties..
  • __unset(): is triggered when calling built-in function unset() on inaccessible properties.
<?php
class MyClass {
  private $arr;

  public function __set($name, $value) {
   $this->arr[$name] = $value;
  }

  public function __get($key) {
   if (array_key_exists($key, $this->arr)) {
    return $this->arr[$key];
   }
   return null;
  }

  public function __isset($name) {
   if (isset($this->arr[$name])) {
    echo "Property $name is set.<br>";
   } else {
    echo "Property $name is not set.<br>";
   }
  }

  public function __unset($name) {
   unset($this->arr[$name]);
   echo "$name is unset <br>";
  }
}
$myObj = new MyClass();
$myObj->name="joe";// will trigger __set
var_dump($myObj);
echo '<br>';
echo $myObj->name; //will trigger __get
echo '<br>';
isset($myObj->name);//will trigger __isset
unset($myObj->name);//will trigger __unset
var_dump($myObj);
?>
Output:
object(MyClass)#1 (1) { ["arr":"MyClass":private]=> array(1) { ["name"]=> string(3) "joe" } }
joe
Property name is set.
name is unset
object(MyClass)#1 (1) { ["arr":"MyClass":private]=> array(0) { } }

Method overloading

__call(), __callStatic

This is a way to dynamically create object methods which do not exist or are inaccessible.

  • __call(): is triggered when calling an inaccessible method of an object.
  • _callStatic(): is triggered when calling an inaccessible static method methods of a class.
<?php
class MyClass {

  public function __call($name, $paramArr) {
    // do something based on method name and params
    return "<br>returning result of method: $name , params: "
      . print_r($paramArr, true) . "<br>";
	}

	public static function __callStatic($name, $paramArr) {
    // do something based on method name and params
    return "<br>returning result of static method: $name , params: "
      . print_r($paramArr, true) . "<br>";
	}
}
$a = new MyClass();
echo $a->someMethod("some arg");
echo MyClass::someStaticMethod("some arg for static method");
?>
Output:
returning result of method: someMethod , params: Array ( [0] => some arg )

returning result of static method: someStaticMethod , params: Array ( [0] => some arg for static method )

Calling object as a function

__invoke() method is triggered when a script tries to call the target object as an function.

It can be used to pass a class instance that can act as a closure, or simply as a function that we can pass around, and can invoke it without knowing if it’s an object or without knowing what object it is.

<?php
class MyClass {

  public function __invoke() {
   //do something on being invoked as a function
    echo "invoked triggered<br>";
  }
}

function myFunction(Callable $func) {
  $func();
  return "returning from myFunction";
}

$a = new MyClass();
//$a() this also works
echo myFunction($a);
Output:
invoked triggered
returning from myFunction

Object Cloning

__clone() method of a newly cloned object is triggered just after it has been cloned by using clone keyword.

__clone() method allows any necessary properties that need to be changed after cloning.

When an object is cloned by using clone keyword, PHP performs a shallow copy of all of the object’s properties. Any properties that are internal object references will not be cloned and will remain references. Using __clone(), we can explicitly cloned internal objects too. There can be an recursive _clone() method calls to achieve deep cloning.

<?php
class MyClass {
  public $var;

  public function __construct() {
   $this->var = new MyOtherClass();
  }

  public function __clone() {
   $this->var = clone $this->var;
  }
}
class MyOtherClass {
  private $str = 'some string';

  function getStr() {
    return $this->str;
  }
}

function toString($bool) {
  if ($bool === false) {
   return 'FALSE';
  } else {
   return 'TRUE';
  }
}
$a = new MyClass();
$b = clone $a;
//using identity operator === to see two '$var' have the same references
echo 'are internal objects equal: ' . toString($a->var === $b->var);
Output:
are internal objects equal: FALSE

removing __clone() method of MyClass will give output of TRUE, confirming that two $var are still pointing to same reference.

Serialization

__sleep() and __wakeup()

__sleep() method triggered when serialize() function is invoke on the target object.

serialize generates a storable string representation of a value.

To deserialize string to PHP type we use unserialize() function. In that case the magic method __wakeup() is invoked on the target object.

The purpose of these two magic methods is to control the ongoing serialization process. __sleep() method returns an array of property names to be serialized. If this method is not defined then all properties are serialized.

<?php
class MyClass {
  public $date;
  public $str;
  function __sleep() {
    return array('date');
  }

  function __wakeup() {
    echo "wakeup triggered <br>";
  }
}

date_default_timezone_set("America/Chicago");
$a = new MyClass();
$a->date = date("y/m/d");
$s = serialize($a);

echo "serialized: <br>";
echo $s;
echo "<br>";

echo "unserializing<br>";
$b = unserialize($s);
echo 'unserialized object:';
echo var_dump($b);
echo "<br>";
echo 'unserialized date: ' . $b->date;
Output:
serialized:
O:7:"MyClass":1:{s:4:"date";s:8:"16/10/25";}
unserializing
wakeup triggered
unserialized object:object(MyClass)#2 (2) { ["date"]=> string(8) "16/10/25" ["str"]=> NULL }
unserialized date: 16/10/25

Exporting variables

The magic method __set_state() of a class is produced in the exported string when we use var_export() function on the instance of the target object.

A variable can be exported to a parsable string representation by using var_export() function. This method is similar to var_dump() but the difference is that var_export() returns a valid PHP code. Which we can import in our program and can reuse it later. For example:
<?php
class A{
  public $prop = 4;
}
echo var_export(new A());
Output:
A::__set_state(array(
   'prop' => 4,
))

Exported var returns a form which would expect a static method call __set_state() on object A and pass the exported object property array. That happens when we try to convert it to PHP variable again. We are supposed to define __set_state() method in our class and recreate the object instance from the array.

One way to reuse the exported string to manually copy paste the code and use it. Another way is to use the function eval(), which is not recommended.

<?php
class TestClass {
  public $var = 4;

  public static function __set_state($arr) {
    $a = new TestClass();
    $a->var = $arr['var'];
    return $a;
 }
}

$a = new TestClass();
$v = var_export($a, true);
echo "exported variable:<br> $v <br>";
echo "<br>importing variable:<br>";
eval('$e=' . $v . ';');
var_dump($e);
Output:
exported variable:
TestClass::__set_state(array( 'var' => 4, ))

importing variable:
object(TestClass)#2 (1) { ["var"]=> int(4) }

Controlling debug info

The magic method __debugInfo() is triggered when we use var_dump() on the target object.

If this method isn’t defined on an object, then all public, protected and private properties will be shown. If it is defined, then it should return an associative array of properties which we want to show in var_dump() call.

class TestClass {
	 private $var = 10;
	 private $str = 'a string';

	 public function __debugInfo() {
		  return ['string' => $this->str];
	}
}

$a = new TestClass();
var_dump($a);
Output:
object(TestClass)#1 (1) { ["string"]=> string(8) "a string" }