10 PHP interview questions and answers – (upwork)

  • Q

    Do you have any experience with LAMP?

    A

    LAMP is an open-source solution stack that contains everything you need to create a complete, stand-alone platform for your web application—Linux, Apache, MySQL, and PHP. This question is a good opportunity for your prospective programmer to detail any experience they have taking a web project from conception to completion.

     

  • Q

    What are PHP sessions and how do they work?

    A

    What you’re really asking is whether they know how to use session_start(). It either creates or resumes a session based on an identifier that is sent to the server via a GET or POST request or a cookie. The most common use case scenario on the web is when a website won’t let you comment or post without first prompting a login. How does it know whether you’re logged in? One way would be to place a cookie in the user’s browser; on every request the cookie is sent server-side, where PHP can be used to determine which information is sent back and displayed to the client. While session_start() saves session data in files by default, it is also possible to store sessions directly in the database.

     

  • Q

    How are classes loaded in PHP?

    A

    This is a good way to gauge a developer’s understanding of autoloading. Whenever a class is instantiated, a function is triggered. You can register a function with the spl_autoload que detailed below, courtesy of php.net:

    bool spl_autoload_register ([ callable $autoload_function [, bool$throw = true [, bool $prepend = false ]]] )

     

  • Q

    What are some of your favorite PHP design patterns?

    A

    Design patterns are basically best-practice templates that programmers can use to consistently write well-designed code more quickly. Here are a couple examples along with their use cases:

    The Singleton: Used when you only want to allow access to one instance of a particular class.

    The Factory: The factory pattern makes it
    easier to create multiple classes without repeating code. To change,
    rename, or replace the class, simply modify the factory.

     

  • Q

    Determine the value of $pear after executing the code below. What will strlen($pear) return? Explain your answer.

    A

    $pear = ‘PEAR ’;
    $pear[12] = ‘PHP Extension and Application Repository’;

    This question reveals a few interesting things about the way PHP interprets code. The value of $pear in the code above will be the string “PEAR P” or the string “PEAR ” followed by seven spaces, followed by “P,” which is the first character in the string “PHP Extension and Application Repository.” The value returned by strlen($pear) will thus be 13. Since an element of a string can only consist of one character, and the count of elements within a string starts with 0, $pear[12] sets the 13th character of the string to the letter “P.” Interestingly enough, we chose to set the 13th value of a string that only has five characters. While other language interpreters might have thrown an out-of-bounds index error, PHP is more forgiving and fills in the blanks with empty spaces.

     

  • Q

    Determine the output of the code below. Explain your answer.

    A

    var_dump(42 == 042);
    var_dump(‘042’ == 42);
    var_dump(‘042’ === 42);

    This question quizzes the coder on how the PHP interpreter handles numbers and strings.
    i. var_dump(42 == 042); will output bool(false) because the PHP interpreter treats leading zeroes as octals. 042 is 32 in decimal, which does not equal 42.
    ii. var_dump(‘042’ == 42); will output bool(true) because PHP interpreter will coerce the string into an integer but ignore the leading zero. 42 is equal to 42.
    iii. var_dump(‘042’ === 42); will output bool(false) because the === operator performs a stricter comparison and will not coerce the integer into a string.

     

  • Q

    Explain why the two code snippets below will evaluate to the same output.

    A

    $x = true or false; $x = true and false;
    var_dump($x); var_dump($x);

    This question is designed to test a coder’s knowledge of the order of operations. The first block of code is more straightforward, evaluating to true because of the “or” operator. The second code block, however, would typically be expected to evaluate to false. Instead, it evaluates to true because of how the PHP interpreter handles the order of operations: “=” is prioritized leading to the following equivalent code snippet:

    $x = true; // sets $x equal to true
    True and false; // evaluates to false, but does not affect anything

     

  • Q

    If $x = 100 + “25%” + “$40” what is the value of $x and why?

    A

    The answer is $x = 125, because PHP uses automatic type conversion in deciding how to treat variables and values depending on how they are used. When PHP encounters a string during an arithmetic operation, it will interpret any numerical value and ignore the remainder in order from left to right. Strings that don’t start with numbers are evaluated to zero.

    $x = 100 + 25 + 0 = 125.

     

  • Q

    Explain the difference between classes and interfaces.

    A

    In layman’s terms, an interface is a class without all the business logic. In an interface, all methods must be public and multiple inheritance is supported. However, all methods must be defined within the class that implements them. Abstract classes, on the other hand, can be declared with modifiers like public or internal, and can define properties or variables. Abstract classes do not support multiple inheritance and can only be extended by one abstract class.

     

  • Q

    Predict the output of the code below. Explain your answer.

    A

    $x = 2
    $y = 4
    $z = 6
    
    
    if($z > $y > $x) {
        echo “true”;
    }else{
        echo “false”;
    }

    At first glance, one would expect the boolean to evaluate to “true” because 6 > 4 > 2. However, the correct answer is “false” because PHP will first evaluate $z > $y, which returns a boolean value of 1 or true. It is this boolean value of 1 that is compared to the next integer in the chain, bool(1) > $z, which will result in NULL and echo “false.”

 

Advertisements

What are exceptions and how to handle them?

Exception handling is an elegant way to handle errors which are beyond the program’s scope. For example, if our application fails to contact the database, we use exception handling to contact another data source or to provide instructions to the users that they need to contact technical support.

Exception handling is an elegant way to handle errors which are beyond the program’s scope.

In this tutorial, we are going to learn how and when to use exception handling and, even more important, when not to use it.

In order to explain the need for exception handling, we will try to see what happens when a program is fed with faulty data. In our example, we will develop the class FuelEconomy that calculates with the method calculate() the fuel efficiency of cars by dividing the distance traveled by the gas consumption.

We will feed the class with the nested array $dataFromCars, in which each nested array has two values: the first value is for the distance traveled and the second value is for the gas consumption. While the first and last nested arrays contain legitimate data, the second nested array provides zero gas consumption and the third nested array has negative gas consumption.

Here is what happens when we feed the array to the class:

Result:
5
Warning: Division by zero
-16.666666666667
6

From the result, we can see what might happen when we feed the class with faulty data. On the second line, we got a nasty warning for trying to divide by zero while, on the third line, we got a negative value (which is not what we would expect for gas efficiency). These are the kinds of errors that we would like to suppress by using exception handling.

How to throw an exception?

When handling exceptions, we make use of the Exception class, which is a built-in PHP class. We throw the exception with the command throw new Exception() that creates the exception object. Between the brackets of the throw new Exception() command, we write our own custom message that we would like to appear in the case of the exception.

In the example given below, whenever the user tries to feed the class with a gas consumption value that is less than or equal to zero, a custom message is thrown instead of an error.

If we run the code as it is written now, we’ll get an even nastier error because, in order to handle exceptions, we need to not just throw the exception but also to catch it.

How to catch an exception?

In order catch an exception, we need two blocks:

  1.  A try block.
  2.  A catch block.

While the try block runs the normal data, the faulty data is handled by the catch block. Inside the catch block, we use methods that the PHP Exception class provides.

In the example given below, the custom error message that we throw from the try block is being caught by the catch block that, in turn outputs the error message with the getMessage() method (which is a method that the Exception class provides).

Result:
5
Message: The gas consumption cannot be less than or equal to zero. You better drink coffee or take a break. Message: The gas consumption cannot be less than or equal to zero. You better drink coffee or take a break.
6
Thanks to exception handling, we now get an elegant error message instead of the nasty one that we got when not using exception handling.

Are there any other methods that can help us handle exceptions?

The Exception class is a PHP built-in class that offers several helpful methods. We have already used the getMessage() method to get a custom error message, yet there are other beneficial methods that the Exception class provides. Of those, the most beneficial are:

  •  getFile() that returns the path to the file in which the error occurred.
  •  getLine() that returns the line in which the exception occurred.

We can now use the getFile() and getLine() methods to add the path and line in which the exception has occurred to the custom message from the above example.

Result:
5
Message: The gas consumption cannot be less than or equal to zero. You better drink coffee or take a break.
File: C:wampwwwindex.php
Line: 9
Message: The gas consumption cannot be less than or equal to zero. You better drink coffee or take a break.
File: C:wampwwwindex.php
Line: 9
6

The result above demonstrates that exception handling can provide more than custom messages. It can provide beneficial data for tracing the exceptions.

What about writing the exceptions to a log file?

In the same way that we can echo the exception messages to the user, we can also write them into a log file with the error_log() command. For example:

In our example, let’s now add the ability to write errors into the log file whenever an exception is thrown:

When to use exception handling?

The sole purpose of exception handling is to handle external problems, such as math errors, logical errors, or technical difficulties.

Exception handling is a great tool that handles specific errors that are outside the scope of a program. These errors might be math errors, logical errors or technical difficulties, examples of which are as follows:

  • Math errors, e.g., trying to divide by zero.
  •  Logical errors happen when trying to do something that doesn’t make sense in the context of the program (like assigning a negative value to gas consumption). •
  • Technical problems are most often caused by hardware failure (like the computer running out of memory) but they can also be the fault of external services (like communication failures or problems with an external API).

It is important to stress that, although exception handling is a great tool for handling errors which are outside the scope of the program in an elegant way, it is not a way to hide bugs or badly written code. It is also not a fancy way to replace if-then and switch statements. The sole purpose of exception handling is to handle external problems, such as math errors, logical errors, or technical difficulties.

Traits and code inclusion

PHP allows a class to inherit from only a single parent class, but sometimes we cannot escape the necessity to use code from more than one resource. In these cases, it is common to chain more and more parents. However, this can easily get quite complicated and it is considered a good practice not to exceed beyond an inheritance tree of three generations. Another common practice is to include the code that we would like to share between the classes by using the ‘include’ or ‘require’ PHP built-in functions. This practice, though valid, is hackish by nature.

This is why we need to consider the use of a trait, a new feature that was introduced into PHP version 5.4, as it allows a class to get its code from more than one trait. In fact, it allows a class to use as many traits as it needs.

How do traits work?  

Traits resemble classes in that they group together code elements under a common name, and with the following syntax:

In the example given below, a trait with the name of Price has a method changePriceByDollars() that calculates the new price from the old price and the price change in dollars.

Once we create a trait, we can use it in other classes with the use keyword. In the example given below, both the classes Bmw and Mercedes use the Price trait.

In order to see our code in action, let’s create objects from the classes and then, let’s make use of the changePriceByDollars() method that they got from the trait.

Result:
48000
39900

From this code example, we can understand that we can use the code from the traits inside the classes in pretty much the same way that we can include a block of code into each of the classes.

Is it possible for a class to use more than one trait?

A class can use more than one trait, after all, this is what traits were invented for.

Let’s present to our code another trait with the name of SpecialSell that has a method with the name of annonunceSpecialSell, and make the Mercedes class use both traits.

Result:
39900
Mercedes on special sell

How is a trait different from inheritance?

Traits use a special form of inheritance that enables them to include the code from the traits in the classes.

  • Traits use a form of inheritance that is known as horizontal inheritance in which the code from the trait is included in the classes in which it is used. It is pretty much like using ‘require’ or ‘include’ in the classes to include code from the outside, albeit not hackish.
  • In a trait it is possible to put concrete (real) methods, abstract methods, properties and even constants.
  •  While the same class can use more than one trait, it can only inherit from one class.
  • Traits do not respect the visibility scope, thus allowing a trait’s methods to access private properties and methods in the class that uses them.

In the example given below, the trait’s method changePriceByDollars() is allowed to interact with the private $price property.

Result:
42000
39900

We can see that the trait’s methods has access to private methods within the classes that use them.

What are the advantages of using traits?

Traits allow us to use code from more than one resource in a class and, by doing so, we are able to circumvent the limitation of single class inheritance.

What are the disadvantages of using traits?

When using a trait, we should be on the lookout for code duplication and for naming conflicts that are the result of calling the methods in different traits with the same name.

Traits may be easily misused, resulting in a code that looks like a patchwork, instead of consisting of well-designed and well-thought of class hierarchies through the use of inheritance.

In which scenarios is it preferable to use traits?

In some cases, the use of traits can save the day and prove to be preferable to using inheritance. Think of a scenario in which number of classes implement the same interface and so share its code, but only a few of the classes (and not all of them) need a certain piece of that code. It is reasonable to use inheritance for those methods that are shared by all of the classes, while leaving it better of to traits to hold the methods that are needed in only some of the classes. For example, if we have three classes that inherit the Car interface (Mercedes, Bmw, and Audi) and we need the method that handles special sell to work in only two of these classes (Mercedes and Bmw), we will use a trait so that the code will be shared only by the classes that need it.

The message to take home is that traits are a tool that allows code inclusion from different resources and so could be quite handy when used appropriately

Static methods and properties

In certain cases, we might want to approach methods and properties of a class without the need to first create an object out of the class. This can be achieved by defining the methods and properties of a class as static. Even though the use of static methods and properties is not considered a good practice, there are cases in which their use is quite handy and justified.

We can access static methods and properties without the need to first create an object, but their use should be limited.

We have already learned about the three access modifiers called public, protected and private. This chapter is devoted to the fourth modifier, static, that allows access to classes’ properties and methods without the need to create objects out of the classes.

How to define methods and properties as static?

In order to define methods and properties as static, we use the reserved keyword static. In the following example, the class Utilis has a static public property with the name of $numCars, and so the property’s name is preceded by both the static as well as the public keywords.

How to approach static methods and properties?

In order to approach static methods and properties we use the scope resolution operator (::). In the example given below, in order to work with the static property of $numCars, we use the following code:

Result:
3
Pay attention to the use of the $ sign right after the scope resolution operator.

How to approach the static methods from within the class?

In the same manner that we used the $this keyword to approach the class’s own properties and methods from within the class, we use the reserved keyword self to approach static methods and properties.

In the example given below, the method addToNumCars() gets and sets the number of cars from the static $numCars property within the same class by using the self keyword.

Result:
0
3
2

When to use static properties and methods?

The main cases in which we consider the use of static methods and properties are for utilities.

The use of static properties and methods is not a good practice. However, in some cases, the ability to use a property or a method without the need to first create an object out of a class can be advantageous. The main cases in which we consider the use of static methods and properties are when we need them as counters and for utility classes.

Use case 1: as counters
We use static properties as counters since they are able to save the last value that has been assigned to them. For example, the method add1ToCars() adds 1 to the $numberOfCars property each time the method is called.

Result:
0
1
2
3

Use case 2: for utility classes

It is very common to use static methods for utility classes. The sole purpose of utility classes is to provide services to the main classes. Utility methods can perform all kinds of tasks, such as: conversion between measurement systems (kilograms to pounds), data encryption, sanitation, and any other task that is not more than a service for the main classes in our application.

The example given below is of a static method with the name of redirect that redirects the user to the URL that we pass to it as an argument

In order to use the redirect() method, all we need to do is call it from the scope of the Utilis class without having the need to create an object. It’s as simple as this:

Utilis :: redirect(“https://rintukumar.wordpress.com/”);

Why static should be used with caution?

Whenever you use static, be sure to use it for utilities and not for convenience reasons.

If you are considering the use of static methods and properties because they are convenient and can be approached without the need to first create an object, please be cautious, because static methods suffer from the following two major disadvantages:

  • Static methods and properties present globals to the code that can be approached from anywhere, and globals are something that we should avoid as much as possible.
  • You will have a hard time performing automated testing on classes that use static methods.

So, whenever you use static, be sure to use it for utilities and not for convenience reasons.

Type hinting

Type hinting forces our functions and methods to get only arguments that belong to a specific class, a specific interface, or to arrays. This practice can be most advantageous because it results in better code organization and improved error messages.
This tutorial explains type hinting for arrays and objects, while type hinting for interfaces will be covered in the next one.
How to do array type hinting?                                                                      
When we would like to force a function to get only arguments of the type array, we can put the keyword array in front of the argument name, with the following syntax:

In the following example, the calcNumMilesOnFullTank() function calculates the number of miles a car can be driven on a full tank of gas by using the tank volume as well as the number of miles per gallon (mpg). This function accepts only array as an argument, as we can see from the fact that the argument name is preceded by the array keyword.

First, let’s try to pass to the function an argument which is not an array to see what might happen in such a case:

Result:                                                                                             Catchable fatal error: Argument 1 passed to calcNumMilesOnFullTank() must be of the type array, string given    This error is a precise description of what went wrong with our code. From it, we can understand that the function expected an array variable, and not a string. Let’s rewrite the code and pass to the function an array with the expected items, including the model names, the tank volumes, and the mpg (miles per gallon).

Result:
Toyota : 528
BMW : 533
Now it’s working because we passed to the function the array that it expected to get.
How to do object type hinting?
Type hinting can also be used to force a function to get an argument of type Object. For this purpose, we put the name of the class in front of the argument name in the function.
In the following example, the class’s constructor can only get objects that were created from the Driver class. We ensure this by putting the word Driver in front of the argument name in the constructor.

Does PHP support type hinting to basic data types?                                                        
It depends. Whereas PHP5 doesn’t allow type hinting for basic data types (integers, floats, strings and booleans), PHP7 does support scalar type hinting.
PHP5 does not support type hinting to basic data types like integers, booleans or strings. So, when we would like to ensure that an argument belongs to a basic data type, we can use one of PHP’s “is_” family functions. For example:

  •   is_bool – to find out whether a variable is a boolean (true or false).
  •  is_int – to find out whether a variable is an integer.
  •  is_float – to find out whether a variable is a float (3.14, 1.2e3 or 3E-10).
  • is_null – to find out whether a variable is null.
  • is_string – to find out whether a variable is a string.

On the other hand, PHP7 does support scalar type hinting. The supported types are: integers, floats, strings, and booleans.
The following code example can only work in PHP7.

Polymorphism in PHP

In this tutorial, we are going to learn a naming convention that can help us write code which is much more coherent and easy to use. According to the Polymorphism (Greek for “many forms”) principle, methods in different classes that do similar things should have the same name.

According to the Polymorphism principle, methods in different classes that do similar things should have the same name.

A prime example is of classes that represent geometric shapes (such as rectangles, circles and octagons) that are different from each other in the number of ribs and in the formula that calculates their area, but they all have in common an area that needs to be calculated. In such case, the polymorphism principle says that all the methods that calculate the area (and it doesn’t matter for which shape or class) should have the same name. For example, we can write in each class that represents a shape a calcArea() method that calculates the area with a different formula. Now, whenever the end users would like to calculate the area for the different shapes, the only thing that they need to know is that a method with the name of calcArea() is used to calculate the area. So, they don’t have to pay any attention to the technicalities of how actually each method works. The only thing that they need to know is the name of the method and what it is meant to do.

How to implement the polymorphism principle?

In order to implement the polymorphism principle, we can choose between abstract classes and interfaces.
In order to ensure that the classes do implement the polymorphism principle, we can choose between one of the two options of either abstract classes or interfaces.
In the example given below, the interface with the name of Shape commits all the classes that implement it to define an abstract method with the name of calcArea().

In accordance, the Circle class implements the interface by putting into the calcArea() method the formula that calculates the area of circles.

The rectangle class also implements the Shape interface but defines the function calcArea() with a calculation formula that is suitable for rectangles:

Now, we can create objects from the concrete classes:

We can be sure that all of the objects calculate the area with the method that has the name of calcArea(), whether it is a rectangle object or a circle object (or any other shape), as long as they inherit from the Shape interface. Now, we can use the calcArea() methods to calculate the area of the shapes:

Result :
28.274333882308
12

Interfaces – the next level of abstraction

Interfaces resemble abstract classes in that they include abstract methods that the programmer must define in the classes that inherit from the interface. In this way, interfaces contribute to code organization because they commit the child classes to the methods that they should implement. The use of interfaces become very helpful when we work in a team of programmers and want to ensure that all the programmers write the methods that they should work on, or even in the case of a single programmer that wants to commit himself to write certain methods in the child classes.

An interface commits its child classes to abstract methods that they should implement.

How to declare and implement an interface?
We declare an interface with the interface keyword and, the class that inherits from an interface with the implements keyword. Let’s see the general case:

In the simple example given below, we will create an interface for the classes that handle cars, which commits all its child classes to setModel() and getModel() methods.

Interfaces, like abstract classes, include abstract methods and constants. However, unlike abstract classes, interfaces can have only public methods, and cannot have variables.
The classes that implement the interfaces must define all the methods that they inherit from the interfaces, including all the parameters. So, in our concrete class with the name of miniCar, we add the code to all the abstract methods.

Can we implement more than one interface in the same class?
We can implement a number of interfaces in the same class.
We can implement a number of interfaces in the same class, and so circumvent the law that prohibits the inheritance from more than one parent class. In order to demonstrate multiple inheritance from different interfaces, we create another interface, Vehicle, that commits the classes that implement it to a boolean $hasWheels property.

Now, our child class can implement the two interfaces.


What are the differences between abstract classes and interfaces?

We saw that abstract classes and interfaces are similar in that they provide abstract methods that can be implemented only in the child classes. However, they still have the following differences:
• Interfaces can include abstract methods and constants, but cannot contain concrete methods and variables.
• All the methods in the interface must be in the public visibility scope.
• A class can implement more than one interface, while it can inherit from only one abstract class.

Let’s summarize these differences in the following table:
interfaces Abstract classes
the code abstract methods  & constant abstract methods   -constants -concrete methods -concrete variables
access modifiers -public -public -protected -private etc.
number of parents The same class can implement more than 1 interface The child class can inherit only from 1 abstract class