📜 ⬆️ ⬇️

PHP Programmer Job Interview Guide

Omnipresent ... this is definitely the word that can describe the PHP language in relation to the web. He is really omnipresent. Currently, among all server programming languages, PHP is used most widely. Over 80% of sites are written on it, while the next most popular ASP.NET with its 17% remains far behind.



Why? What allowed PHP to become so popular and widely used? There is no definite answer to this question, but the ease of use of the language is certainly an essential factor contributing to its success. Beginners in PHP can quickly reach a sufficient level and place dynamic content on their websites with a minimum of programming knowledge.
')
This is the main problem of finding highly qualified PHP developers. The relatively low threshold of entry and 20 years of language development has led to the fact that PHP-programmers have become as ubiquitous as PHP itself. Many of them can legitimately say that they "know" the language. However, developers who really are experts in PHP, are able to create much more functional, reliable, scalable and easy to maintain software.

How to distinguish those who have real competence in PHP (not to mention those who belong to the 1% most experienced candidates) from those who have only superficial knowledge?

From the translator: this text is a translation and adaptation with small additions to the article The Insider's Guide to PHP Interviewing , the link to which was published in the latest PHP digest in June. I tried to convey the meaning of the original as much as possible, added a few explanations, significantly increased the number of references to documentation, and also added links to articles from the Habr and other sources. An important difference from the original: added navigation for questions, part of the code and text is hidden under the spoilers.

This guide offers several questions to help you effectively assess the breadth and depth of ownership of a PHP candidate. It should be borne in mind that they are only guidelines. Not every high-class candidate worthy of hiring will be able to correctly answer all the questions, just as the answer to them does not guarantee that the candidate will suit you. After all, recruiting is more art than science.

Please note that we focused on modern versions of PHP (5.3 and older), but there are also references to concepts and functions that have been around for quite a long time, and therefore familiar to all qualified PHP developers.

A list of questions


  1. Tell about closures in PHP. Give examples of when, why and how can they be used?
  2. Explain why and how the global keyword is used. Give an example when its use is appropriate and when not.
  3. Tell about namespaces in PHP and why they are useful.
  4. What are types (traits)? Describe their main characteristics and tell them how useful they are. Give an example of the declaration of a type and a class that uses several types.
  5. Tell us how php: // input and $ _POST are interconnected and how to get access to the php: // input stream?
  6. Name at least five superglobal variables whose names begin with $ _, and give them a definition. Tell them about their relationship with the $ GLOBALS variable.
  7. Explain the purpose and use of the magic methods __get, __set, __isset, __unset, __call, and __callStatic. When, how and why should they be used (or not used)?
  8. Describe several data structures from the PHP Standard Library (SPL). Give examples of use.
  9. What would be $x after executing $x = 3 + "15%" + "$25" ?
  10. Explain the purpose of the static keyword when calling a method or accessing a property. Tell us when and why it should be used, and how it differs from the keyword self. Give an example.
  11. Tell us about the internal structure of arrays in PHP?
  12. What is the difference between ArrayAccess and ArrayObject?
  13. What are generators? When can they be used instead of iterators and regular arrays? What are the keywords yield and send for?
  14. List the key differences between PHP versions 5.3, 5.4, 5.5.


Key Concepts and Paradigms


There are a number of basic concepts and paradigms, without the knowledge of which one cannot be considered an expert in PHP. Here are some examples.

Question : Tell us about closures in PHP . Give examples of when, why and how can they be used?

Closures are useful in situations where some of the logic must be executed in a limited context, but it must also be able to interact with the environment external to this context.

The first building block for closure is anonymous (lambda) functions, i.e. such functions that have no associated names. For example:

 // 2-   array_walk -   array_walk($array, function($dog) { echo $dog->bark(); }); 

Although anonymous functions do not have a name associated with them, they can be associated with variables or passed as a callback parameter to a higher order function . Example:

 //       //   $dogs_bark $dogs_bark = function($dog) { echo $dog->bark(); } array_walk($array, $dogs_bark); 

The internal structure of closures in PHP is represented by a special class of closures - Closure .
The content of an anonymous function exists in its scope regardless of the scope in which the function was created. However, you can explicitly associate one or more variables from the external scope, which can be referenced in the scope of an anonymous function. To do this, use the use construct when defining an anonymous function.

Code example
 class Dog { public function bark() { echo 'woof'; } } $dogs_bark = function($dog) use (&$collar) { //    if ($collar == 'fitsWell'){ echo $dog->bark(); // 'woof' } else { echo 'no bark'; //  ($collar)    } }; $dog = new Dog; $collar = 'fitsWell'; //   $dogs_bark($dog); // 'woof' $collar = 'tight'; $dogs_bark($dog); // 'no bark' 


The ability to access external variables within a closure is especially useful when using higher order functions. Take, for example, the function array_walk($array, $calback) , which, like other similar functions, allows you to bypass the set of variables passed to it and process them in a specific way. This function bypasses the $array and at each iteration calls an anonymous function ( $callback ), passing to it only the value of the current element and its key. Therefore, the use of the $ collar variable without closure and the use construction will fail. Of course, we can use the global , but this will lead to the senseless cluttering of the global variable namespace, which is needed only in this particular context.
Closures have additional object-oriented features. Starting with PHP 5.4, new methods have appeared in the interface of the Closure class: bind() and bindTo() , which can be used to bind new objects to the closure. For example:

 Closure::bindTo($newthis, $newscope); 

This method duplicates the closure and binds its scope to a new object in such a way that inside the closure the $this variable will become a reference to $newthis in the object context. Let's change the $dogs_bark function so that it uses the $this variable, and then bind it to the $dog object.

 //  ,       $dogs_bark = function() { echo $this->sound; //  sound -   $this }; $new_dog = new Dog(); //         $new_dog $new_closure = $dogs_bark->bindTo($new_dog); $new_closure(); //    $sound 

Binding a closure to a variable and gaining access to $this is a fairly powerful feature. In particular, we can assign a closure to a property of an object, essentially turning it into a method of this object.

 $dog = new Dog(); $dog->closure = $dogs_bark; $dog->closure(); 

As a result, we can change the behavior of an object at run time without having to redefine the class signature. This feature is useful in those situations when the functionality needs to be improved, but the code cannot be changed, or the change is necessary in a limited context.
To the list of questions

Question: Explain for what purpose and how the global keyword is used. Give an example when its use is appropriate and when not.

In the past, PHP's object-oriented features were much simpler than they are now, and therefore you can often come up with outdated code that actively uses the global . In many ways, the use of global variables is a spit in the face of all the best practices of object-oriented programming. It leads to the emergence of excessive interdependence between classes, complicates the separation of logic, leads to pollution of the global namespace by variables that are used in one particular context and are not needed in others.

Consider a simple example:
 class Dog { function bark() { global $sounds; return $sounds->bark(); } } 


The code demonstrates the emergence of the hidden dependency of the Dog class on the $sounds global variable. Of course, there are cases when it is justified (suppose there is a single set of sounds in the system that never changes at all), but it is much better to explicitly transfer $sounds object of the Dog class in the constructor, and store and use it within this instance:
Code example
 class Dog { protected $sounds; function __construct($sounds) { $this->sounds = $sounds; } public function bark() { return $this->getSounds()->bark(); } public function getSounds() { return $this->sounds; } } 


But, as often happens in programming, never say never. There are a number of reliable and stable products written in PHP that actively use global variables: Wordpress , which runs about 20% of all sites (and this number grows from year to year), Joomla! 1.5 (yes, it is still widely distributed) and the iLance Enterprise Auction system are all examples of successful projects that have used global variables for many years. Similarly, you may have situations in which global variables will be relevant, but you should be careful when using them.
To the list of questions

Q : Tell us about the namespaces in PHP and why they are useful.

One of the object-oriented innovations in PHP 5.3 is the namespace. As the name implies, the namespace defines such a scope in a program, within which the names of classes, interfaces, functions, variables and constants will not cause conflicts with elements that have the same name in another namespace.

Before PHP 5.3, classes were often given long names to reflect the structure of packages in their names and to avoid name conflicts. Suppose we have a class Dog , defined in the application model Dog_Pound . Without a namespace, the full class name would look like this:

 class Dog_Pound_Model_Dogs { // ,   function getDogs(); } 

The explicit assignment of a namespace, in the scope of which all elements (classes, variables, etc.) will be defined, allows the developer to solve this problem. When using a namespace, the above verbose class name can be replaced by the following:

 namespace dog_pound\model; //     class Dogs { //   "Dogs"  dog_pound\model function getDogs(); } $dogs = new Dogs; //     , // ..          

Relative references to namespaces are also supported. For example, when you are in the dog_pound space, you can create an instance of the Dogs class like this:

 $dogs = new model\Dogs //   "model"   dog_pound 

In addition, elements from one namespace can be imported to another and used directly in it (that is, without references to the original namespace). This can be achieved using the use keyword:

 namespace this\new\namespace; //    //  Dogs   dog_pound\model use dog_pound\model\Dogs; $dogs = new Dogs; 

To the list of questions

Question : What are traits, traits? Describe their main characteristics and tell them how useful they are. Give an example of the declaration of a type and a class that uses several types.

Types are a great addition that appeared in PHP 5.4, allowing you to add behavior to a class without the need to extend the parent class through inheritance (up to version 5.4, this could be done using an impurity pattern). It is important to note that in the context of a single class, you can use several types. Their use helps to improve the organization of the code and the separation of duties, and also corresponds to the well-known design principle , which says: “prefer composition to inheritance”.

A couple of examples of typecasting:
 trait Movement { public function topSpeed() { $this->speed = 100; echo "Running at 100 %!" . PHP_EOL; } public function stop() { $this->speed = 0; echo "Stopped moving!" . PHP_EOL; } } trait Speak { public function makeSound(){ echo $this->sound . PHP_EOL; } } 


Now let's use the use keyword, but not to import a namespace, but to include types in the class definition:
Code example
 class Dog { use Movement, Speak; //    Dog      protected $sound; function __construct() { $this->sound = 'bark'; } } $dog = new Dog(); $dog->topSpeed(); //   Movement $dog->stop(); //   Movement $dog->makeSound(); //   Speak 


To the list of questions

PHP on the fingers


Memorizing things that are easily found in a language specification or API documentation is not an indication of mastery. Nevertheless, everyone who is intimately familiar with the language knows its syntactic and functional features and nuances on the fingers. Here are some questions that allow you to evaluate the candidate from this side.

Question : Tell us how php://input and $_POST are interconnected and how to get access to the php: // input stream?

In simple terms, $_POST is a superglobal array representing the analyzed and formatted request body sent to the server by the post method.
Sample Query Text
 POST /php-hiring-guide/php-post.php HTTP/1.1 Host: toptal.com Referer: http:///toptal.php/php-hiring-guide/php.php Content-Type: application/x-www-form-urlencoded Content-Length: 63 article_name=PHP Hiring Guide&tag_line=You are hired!&action=Submit 


Access to the request body can be obtained through the input stream in the same way that any files are read:
 $input = file_get_contents("php://input"); 

To the list of questions

Question : Name at least five superglobal variables whose names begin with $_ , and give them a definition. Tell them about their relationship with the $GLOBALS variable.

List of superglobal variables
$_POST is an associative array containing key-value pairs sent to the server by the post method.
$_GET is an associative array containing key-value pairs sent to the server using the get method.
$_REQUEST - the union of key-value pairs from $ _POST and $ _GET.
$_SERVER - represents the web server parameters related to the execution of the program.
$_ENV - contains values ​​related to the server (host) and its configuration.
$_SESSION is an associative array that stores the values ​​of session variables between page transitions and application launches.
$_COOKIE - provides access to variables stored in cookies on the client.
$_FILES is a special array for input data received when sending files to the server using the post method.

The $GLOBALS superglobal variable is a relative of the global . The $GLOBALS array stores all variables available in the global scope, including superglobal arrays. For example, access to $_ENV can be accessed like this: $GLOBALS['_ENV'];
To the list of questions

Question : Explain the purpose and application of the magic methods __get , __set , __isset , __unset , __cal l, and __callStatic . When, how and why should they be used (or not used)?

The first four methods in our list are used to overload object properties . They allow you to determine how the outside world will interact with the properties declared with the visibility modifier private or protected , or not at all in the object.

Code example
 //  'whiskers'     Dog, //    __get: function __get($name) { if ($name == 'whiskers') { //   whiskersService   if (! isset($this->whiskersService)) { $this->whiskersService = new Whiskers($this); } //    'whiskers'    whiskersService return $this->whiskersService->load(); } } 


Now you can simply access the 'whiskers' property:

 $hairs = $dog->whiskers; 


Using the __get method to intercept links to properties that look like public ones, we are able to hide the implementation details of these properties.
The __set method __set applied in the same way:

Code example
 function __set($name, $value) { if ($name == 'whiskers') { if ($value instanceOf Whisker) { $this->whiskersService->setData($value); return $this->whiskersService->getData(); } else { throw new WhiskerException("That's not a whisker"); return false; } } } 


Changing the value of the 'whiskers' will look like this:

 $dog->whiskers = $hairs; 

This expression will automatically call the __set() method with passing the property name ( 'whiskers' ) as the first parameter and the right side of the assignment operator as the second.

Finally, __isset and __unset complete a quartet of methods for overloading properties. Each of them takes only one parameter - the name of the property, and is called when performing the isset() and unset() operations on this property.
Code example
 function __isset($name) { if ($name == 'whiskers') { return (bool) is_object($this->whiskersService) && !empty($this->whiskersService->getData()); } } function __unset($name) { if ($name == 'whiskers' && is_object($this->whiskersService)) { //       $this->whiskersService->reset(); } } 


The two remaining methods, __call and __callStatic , perform a similar function, allowing you to implement method overloading . They allow us to determine how a class and its instances respond to attempts to invoke undefined, protected, or private methods.

Note translator: __call is called when a member is accessed in the context of an object, and __callStatic when a static member is accessed. As arguments, they both take the name $name method being called and the $args array with the parameters passed to the $name method.

For example, this implementation of __call will lead to the fact that when accessing any "invisible" method, the whiskersService will be whiskersService :

 public function __call($method, $args) { return $this->whiskersService->load(); } 

The __callStatic method works in the same way and takes the same arguments, but it is called when accessing the “invisible” method not in the context of an object, but in a static context. If we define this method, we will be able to handle calls like ClassName::notVisibleMethod() .

 public function __callStatic($method, $args) { if (!is_object(static::$whiskersService)) { static::$whiskersService = new Whiskers(__CLASS__); } return static::$whiskersService->load(); } $hairs = Dog::whiskers(); 

In the examples above, we encapsulated the implementation of whiskers from the outside world, making it the only object available in this way. Clients of the methods and properties defined by us know nothing about the base class of whiskersService and how Dog stores its data in general.

Together, these methods improve the possibilities for a flexible composition. The degree of abstraction of objects, encapsulation, compactness of the code (and, as a consequence, the controllability of the system) also increases.

Using magical methods, it should be remembered that the benefits obtained come at a price. First, these methods run slower than accessing explicitly defined public properties, as well as slower installers and recipients. Secondly, they prevent the use of many useful tools, such as reflection , autocompletion in IDE, utilities of automatic documentation (for example, PHPDoc). If these things matter, then it may be worth defining public methods and properties explicitly. As in many other cases, the question of whether to use magic methods cannot be answered unambiguously. Strengths and weaknesses must be assessed in each case.
To the list of questions

Question : Describe several data structures from the PHP Standard Library (SPL). Give examples of use.

The PHP development process is mostly related to receiving and processing data from various sources, such as databases, local files, remote APIs, etc. Developers spend a lot of time organizing data, getting it, moving and processing it. The most commonly used structure for representing data in PHP is an array. However, in some cases, arrays are not suitable for solving problems due to insufficient performance and excessive memory consumption, and therefore more suitable data structures are required.

Taking into account how often they talk a lot about frameworks, finding a developer with serious development experience with a framework from your project becomes a daunting task. Ultimately, the activity of the developer community leads to a decrease in the number of programmers working with one specific framework, and redistribution in favor of others. Because of this, it is quite difficult to find a developer with the necessary skills.

The use of the standard PHP library (Standard PHP Library, SPL) and knowledge of its composition is an area whose possession can confirm the competence of a PHP developer. If a candidate has a decent experience with SPL, then most likely he will be able to successfully work on your application, regardless of the frameworks used in your environment.

Including the candidate must know the data structures provided in the PHP documentation. Many of them have similar functionality, but small differences allow them to be used in specific situations.

List of SPL data structures with brief explanations
SplDoublyLinkedList is a doubly linked list. Each node of such a list stores a link to the previous one and to the node next to it. Imagine that you are in line at the bank and you can only see the person in front of you and behind you. This is an analogy of the relationship between the elements in SplDoublyLinkedList . Inserting an item into the list corresponds to the situation when someone got into the queue, and you suddenly forgot who was standing in front of you (and this someone forgot about you). .

SplQueue SplStack SplDoublyLinkedList . , , ( IT_MODE_LIFO – Last In First Out – , ; IT_MODE_FIFO – First In First Out – , ), , . , SplQueue enqueue() dequeue() push() pop() SplStack .

SplHeap – , , . , compare() , .

SplMaxHeap SplMinHeap — SplHeap . SplMaxHeap compare() , , SplMinHea p – .

SplPriorityQueue – , SplHeap , SplHeap priority (), .

SplFixedArray – , . , , , , SplFixedArray ( ).

SplObjectStorage – , , . .

SPL .


: $x $x = 3 + "15%" + "$25" ?

– 18. .

PHP , , .

, , , . , , . , , .

, , $x = 3 + "15%" + "$25" "15%" 15, "$25" — . 18 (3 + 15 + 0).

, – PHP. , ( «15» 15 ). , , (.. ).


: static . , , self . Give an example.

PHP, 5.3, . « » , static ( static:: ) , , , . , « » , .. static .

 class Dog { static $whoami = ''; static $sound = ''; function makeSounds() { echo self::makeSound() . ', '; echo static::makeSound() . PHP_EOL; } function makeSound() { echo static::$whoami . ' ' . static::$sound; } } Dog::makeSounds(); 


: « , ».
:

 class Puppy extends Dog { static $whoami = ''; static $sound = ''; function makeSound(){ echo static::$whoami . ' '; } } Puppy::makeSounds(); 

, : « , ». , , makeSounds() Dog .

makeSounds() self::makeSound() . self:: , ( Dog ). self::makeSound() makeSound() Dog . , Puppy::makeSounds(), .. Puppy makeSounds() , makeSounds() Dog . , Puppy::makeSounds() self::makeSound() , « ».

makeSounds() Dog static::makeSound() . static:: , self:: . static:: , ( , Puppy ). , static::makeSound() makeSound() Puppy . Puppy::makeSounds() static::makeSound() « ».



PHP


, PHP « » – , PHP. , - , , .

: PHP?

PHP. , . , , -. PHP C, – C . PHP- C -, PHP- ( , ) . -.
- O(1) ( ) , (- , ).

Note : (bucket, ), .. . -, .

PHP . , , PHP .

, , . , , , . .


: ArrayAccess ArrayObject ?

ArrayAccess – , : offsetGet , offsetSet , offsetExists , offsetUnset .

ArrayObject – , ArrayAccess . ArrayObject , , [], : $dogs['sound'] , offsetGet(' ') , : $dogs->offsetGet('sound') .
.


: ? ? yield send ?

, . (, foreach ), Generator , , , Iterator . , , . , , , :

  1. , . rewind() ;
  2. , , .. - ;
  3. .


return – . yield (, yield $dog ). return , – .

yield , . send (, $generator->send(-1); ).

:

 function dog_generator() { foreach (range(0, 2) as $value) { //     $dog = DogHelper::getDogFromDataSource($value); //  input  send   $dog $input = (yield $dog); if ($input == -1) { return; //   } } } 

, yield , .

, :

 //        $generator = dog_generator(); foreach ($generator as $dog) { // $dog -    yield echo $dog . PHP_EOL; //     if ($dog == 'Terrier') { //      yield $generator->send(-1); echo '  ,  '; } } 

, :

     ,   


, , .
, , . , , .
php.net .


Overall picture


: PHP 5.3, 5.4, 5.5.

PHP 5.3 2009 , . : , -, .

PHP 5.4 2012 . (), [] (, ['-', ''] ). , register_globals .

PHP 5.5 2013 , . ( yield ), try/catch finally , APC Cache OpCache ( Zend Optimizer). (['-', ''][1] ''), (, '6e5d4'[0] «6»).



PHP- , PHP- – . , , , , . , .. , , .

Source: https://habr.com/ru/post/230805/


All Articles