Get PhpDoc @params of a method

A well-written PhpDoc is a goldmine of information. It may feel redundant, however, to document values that you use in your code too. Why not parse the PhpDoc itself and use that value? Reflection is the way to go.

Consider an Api class that requests users by ID from the Api’s user endpoint. We like to document the name of this endpoint in the PhpDoc for documentation purposes.

class Api {
/**
*
@param int $id
*
@return User
*
@endpoint users
*/
public function user(int $id) : User {
$this->request('users', $id);
}
}
Continue reading Get PhpDoc @params of a method

Chunk an Iterator into Arrays

Iterators can take the heat out of memory consumption when processing big datasets. Typical for such datasets is that workers process them in manageable chunks of a limited size. As these workers typically are independent of each other, it might be necessary to pack chunks of the source in arrays that can be sent with the job metadata to the worker. This is when you might want to chunk an iterator into arrays.

A Generator function is useful to achieve this purpose. As opposed to a normal function, a generator function yields return values as the caller asks for them. Take this dice roller:

function dice() {
return rand() % 6 + 1;
}

Now, let use create a generator function that takes an iterator and a number $n indicating the (maximum) chunk size.

function chunk_iterator(Iterator $it, int $n)
{
$chunk = [];

for($i = 0; $it->valid(); $i++){
$chunk[] = $it->current();
$it->next();
if(count($chunk) == $n){
yield $chunk;
$chunk = [];
}
}

if(count($chunk)){
yield $chunk;
}
}

After starting with an empty $chunk array, loop over all entries of the iterator. Add each entry to $chunk. Check whether count($chunk) reached limit $n, yield $chunk, empty $chunk.

for($i = 0; $it->valid(); $i++){
$chunk[] = $it->current();
$it->next();
if(count($chunk) == $n){
yield $chunk;
$chunk = [];
}
}

After iteration, there might remain some items in a non-full chunk. Output it as well:

count($chunk)){
yield $chunk;
}

Calling the function returns a Generator, which implements the Iterator interface.

// For demonstration, create an iterator from array
$arr = range(20, 40, 1);
$it = new ArrayIterator($arr);

// Iterate over the generator
foreach(chunk_iterator($it, 6) as $c){
echo implode(',', $c)."\n";
}

… and there we go:

20,21,22,23,24,25
26,27,28,29,30,31
32,33,34,35,36,37
38,39,40

Try it yourself on 3v4l.org/dMjCI

Symlinks cause ‘Not valid template file’ in Magento 1.9.3.4

Keeping Magento shops up to date is important to reduce their vulnerability. Sometimes, security updates introduce breaking changes. The recent Magento update, version 1.9.3.4, includes such a breaking change that can cause blank pages on the front-end and back-end. This is caused by the way in which Magento handles symlinks. 

When blank pages occur, take a look at Magento’s system.log file. You might find entries like the following:

Continue reading Symlinks cause ‘Not valid template file’ in Magento 1.9.3.4

Random values from PHP array one-liner

PHP provides the array_rand( $arr, $num ) function which returns an integer or array containing the keys of the array.

To obtain an array of values the following one-liner can be used:

This picks $num random keys from $arr (array_rand), flips keys with values (array_flip), intersects the picked keys with those of $arr (array_intersect_keys) and returns the corresponding elements of $arr.

Getting random values from an array.

Continue reading Random values from PHP array one-liner

Laravel 5 Cron expression validation

A Cron expression validator is created in Laravel 5.3. Laravel provides a versatile and extendable Validation class. Introducing new validations is done by registering a validation function with the extend method on the Validation facade. A Cron expression validator is created by utilising a cron-expression parser.

The cron-expression parser used here is the fantastic cron-expression Composer package by Michael Dowling.

Continue reading Laravel 5 Cron expression validation

Fix Magento 1.9.3 ‘Notice: Undefined index: session_expire_timestamp in … on line 461’

Some days ago the Magento security update SUPEE-8788 was released. This update fixes a number of critical vulnerabilities. To fix an existing shop one could either apply the SUPEE-patch or upgrade the shop to Magento 1.9.3. However, after updating I experienced a little issue when trying to reach the shop again. 

A PHP Exception popped up:

Even after flushing the cache this problem appears. The undefined index and path of the file that raises the exception gives away that this problem might have to with Magento’s session handling. I started with deleting any existing session cookies in my browser. This made the error message disappear. Be aware that this is not an appropriate solution to this error!

Continue reading Fix Magento 1.9.3 ‘Notice: Undefined index: session_expire_timestamp in … on line 461’

Form submission CSRF issues in Magento 1.9.2.2

Magento now includes CSRF (Cross-Site Request Forgery) protection on publicly available forms such as the new user registration form. The goal of this is to make it impossible for anyone to POST to an URL without first visiting the corresponding form page. A token is supplied on this page that is sent along with the rest of the form to the server. The server validates the correctness of the token and responds in a sensible way if the token is correct. If the token is not however, the server ignores the POST request.

Continue reading Form submission CSRF issues in Magento 1.9.2.2