PHP call_user_func vs just calling function

Always use the actual function name when you know it.

call_user_func is for calling functions whose name you don’t know ahead of time but it is much less efficient since the program has to lookup the function at runtime. Also useful if you don’t know how many arguments you are passing. call_user_func calls functions with a series of individual parameters.

call_user_func_array calls functions with array of parameters.

PHP ArrayAccess and ArrayObject

In very simple terms, ArrayAccess is an interface, which you can implement in your own objects; ArrayObject, on the other hand, is a class, which you can either use or extend.

ArrayAccess is an interface built in to PHP which lets you dictate how PHP behaves when an object has array syntax (square brackets) attached to it. Interfaces are collections of function prototypes that we can use as templates for our own code. If you read the manual page for ArrayAccess, it shows four functions:

ArrayAccess {
/* Methods */
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
}

The ArrayObject is a class that you can extend to create objects that behave as if they were arrays. It implements methods like count and sort that enable you to treat an object like you would treat an array. It’s part of the SPL (Standard PHP Library).

ArrayObject is an object, you can implement and extend it as you usually would. It implements a bunch of useful interfaces and wraps them up into an object. For creating an object to look a lot like an array, take a look at ArrayObject! It implements ArrayAccess as we saw above, but also Countable, Traversable, and others.

ArrayAccess vs ArrayObject

PHP Generators

Generators are functions that provide a simple way to loop through data without the need to build an array in memory. “yield” is the main command here.

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        yield $i;
    }
}

foreach (getRange(PHP_INT_MAX) as $range) {
    echo "Dataset {$range} 
"; }

Dissecting the getRange function, this time, we only loop through the values and yield an output. yield is similar to return as it returns a value from a function, but the only difference is that yield returns a value only when it is needed and does not try to keep the entire dataset in memory.

Why we use generators?
There are times when we might want to parse a large dataset (it can be log files), perform computation on a large database result, etc. We don’t want actions like this hogging all the memory. We should try to conserve memory as much as possible. The data doesn’t necessarily need to be large — generators are effective no matter how small a dataset is.

Generators can be key-value too :

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        $value = $i * mt_rand();

        yield $i => $value;
    }
}

Generators can also take in values. This means that generators allow us to inject values into them. For example, we can send a value to our generator telling to stop execution or change the output.

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        $injected = yield $i;

        if ($injected === 'stop') return;
    }
}

$generator = getRange(PHP_INT_MAX);

foreach ($generator as $range) {
    if ($range === 10000) {
        $generator->send('stop');
    }

    echo "Dataset {$range} 
"; }

https://scotch.io/tutorials/understanding-php-generators

json_encode vs serialize

1) json_encode will produce a smaller string and is easy to read.
2) JSON is more portable. json is easily understandable by Javascript as well
3) JSON will have no memory of what the object’s original class was (they are always restored as instances of stdClass).

Implement a Linked List in PHP

class Node {
  public $val;
  public $next;

  function __construct($val) {
      $this->val = $val;
      $this->next = $null;
  }
}

class LinkedList {
  public $head;

  function __construct() {
      $this->head = null;
  }

  function InsertNode($val) {
      $node = new Node($val);
      if ($this->head) {
          $current = $this->head;
          while ($current != null) {
              $prev = $current;
              $current = $current->next;
          }
          $prev->next = $node;
      } else {
          $this->head = $node;
      }
  }

  function PrintAll() {
      $current = $this->head;
      while ($current != null) {
          print $current->val . "\n";
          $current = $current->next;
      }
  }
}

$linkedList = new LinkedList();
$linkedList->InsertNode(1);
$linkedList->InsertNode(3);
$linkedList->InsertNode(2);

$linkedList->PrintAll();

PHP Reading from command line

$handle = fopen ("php://stdin","r");
// if single input (having no spaces)
fscanf($handle,"%d",$n);
// if trying to read 2 values separated by a space
fscanf($handle,"%d %s",$d,$s);
// if trying to read a string having spaces
$inp = trim(fgets($handle));

Advanced Features of PHP

1) Late Static Binding:
“Late binding” comes from the fact that static:: will not be resolved using the class where the method is defined but it will rather be computed using runtime information.

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test();

Instead of “self::who()” replace with “static::who()”. Then the output will be “B” instead of “A”.

2) Variable Length Argument Lists :

func_num_args() ==> returns number of arguments passed
func_get_arg(int) ==> returns the nth argument passed in
func_get_args() ==> returns an array of all arguments

New Features in PHP 7

https://blog.feryn.eu/php-7-is-now-available-new-features-improvements/

1) Speed

2) Type Declarations:
Since PHP 5, you can use type hinting to specify the expected data type of an argument in a function declaration, but only in the declaration.  Besides only being used in function declarations, we were also limited to basically 2 types. A class name or an array.  When you call the function, PHP will check whether or not the arguments are of the specified type. With PHP 7 we now have added Scalar types. Specifically: int, float, string, and bool.

function stringTest(string $string) {
    echo $string;
 }

Additionally, PHP 7 gives us the opportunity to enable strict mode on a file by file basis. We do this by declare(strict_types=1); at the top of any given file.

PHP 7 also supports Return Type Declarations which support all the same types as arguments. To specify the return type, we add a colon and then the type right before the opening curly bracket.

function getTotal(float $a, float $b) : float {

3) Error Handling :
In PHP 7, an exception will be thrown when a fatal and recoverable error occurs, rather than just stopping the script. Fatal errors still exist for certain conditions, such as running out of memory, and still behave as before by immediately stopping the script. An uncaught exception will also continue to be a fatal error in PHP 7. This means if an exception thrown from an error that was fatal in PHP 5 goes uncaught, it will still be a fatal error in PHP 7.

A big change in PHP 7 is the fact that errors are no longer raised the way they used to be raised. Errors now behave in a similar way as exceptions. This means that errors can now be caught in a try/catch block. You can catch both exceptions and errors as Throwables, but you can also catch errors as Error objects. We point out that other types of errors such as warnings and notices remain unchanged in PHP 7. Only fatal and recoverable errors throw exceptions.

interface Throwable
    |- Exception implements Throwable
        |- ...
    |- Error implements Throwable
        |- TypeError extends Error
        |- ParseError extends Error
        |- ArithmeticError extends Error
            |- DivisionByZeroError extends ArithmeticError
        |- AssertionError extends Error

Throwable may be used in try/catch blocks to catch both Exception and Error objects (or any possible future exception types). Remember that it is better practice to catch more specific exception classes and handle each accordingly. However, some situations warrant catching any exception (such as for logging or framework error handling). In PHP 7, these catch-all blocks should catch Throwable instead of Exception.

4) New Operators (Spaceship Operator, Null Coalesce Operator) :

Spaceship Operator (useful in sort algorithms, etc)

$compare = 2 <=> 1
2 < 1? return -1 2 = 1? return 0 2 > 1? return 1

the Null Coalesce Operator, is effectively the fabled if-set-or.
If $firstName is empty then set it to Guest.

$name = $firstName ??  "Guest";

Can be chained.

$name = $firstName ?? $username ?? $placeholder ?? “Guest”; 


5) Anonymous Classes :

Anonymous classes are useful when simple, one-off objects need to be created.

$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});

http://blog.teamtreehouse.com/5-new-features-php-7

6) Closure:Call() Method:

Closures are anonymous functions that are declared inline and assigned to a variable. It can be used as a callback for later execution. In PHP 5 it was already possible to bind an object to the scope of the closure as if it was a method.

The “call” method is one of the PHP 7 features that was introduced to simplify the process.

What is the difference between array_map, array_walk, array_filter, array_reduce in PHP?

array_walk() Applies the user-defined callback function to each element of the array array. Returns a boolean. May or May not Modify the original array. To modify original array callback function can accept an argument by reference.

array_map() returns an array containing all the elements of array1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map(). So array_map does not modify the original array.

array_filter() Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array. Array keys are preserved.
Returns subset of array.

array_reduce() applies iteratively the callback function to the elements of the array, so as to reduce the array to a single value. Returns single value.

The idea of mapping an function to array of data comes from functional programming. You shouldn’t think about array_map as a foreach loop that calls a function on each element of the array (even though that’s how it’s implemented). It should be thought of as applying the function to each element in the array independently.

In theory such things as function mapping can be done in parallel since the function being applied to the data should ONLY effect the data and NOT the global state. This is because an array_map could choose any order in which to apply the function to the items in (even though in PHP it doesn’t).

array_walk on the other hand it the exact opposite approach to handling arrays of data. Instead of handling each item separately, it uses a state (&$userdata) and can edit the item in place (much like a foreach loop). Since each time an item has the $funcname applied to it, it could change the global state of the program and therefor requires a single correct way of processing the items.

Back in PHP land, array_map and array_walk are almost identical except array_walk gives you more control over the iteration of data and is normally used to “change” the data in-place vs returning a new “changed” array.

http://stackoverflow.com/questions/3432257/difference-between-array-map-array-walk-and-array-filter