<?php
namespace abc;
use function is_string;
use function get_class;
class main {
protected $string;
public function __construct( $string ) {
if ( is_string( $string )) {
$this->string = $string;
} else {
$this->string = get_class( $this );
}
}
}
Nothing fancy. Just a class in a namespace using two functions from the global namespace (is_string & get_class). Those two functions are imported from the global namespace as that will give a small performance boost.
But if you have 20-30 build in PHP functions that list will get very long….
Luckily you can merge them:
use function is_string, get_class;
For now I’m not sure I’ll always import build in PHP functions, the boost is small. And it’s annoying to keep track of.
Today we will handle a case of “Premature Optimization Is the Root of All Evil“. But this is my blog and I was working with a very big api set, and will only get bigger, so (premature) thinking about memory usage and execution time might be a good idea in the long run.
Before I started this I thought that a for loop was faster then a foreach loop. And I usually pick foreach because it’s easier to write and read.
A quick google lands on a stackoverflow question which concludes the opposite. So I started to test a bit.
There is a big difference in my use case here.
I need to remove array items that need to be excluded from the api results. Most examples you will find online are about editing items.
First tests where quite clear, using a foreach was in most configurations faster than for. The test array I create has 10000 items and every 3rth item should be excluded:
The same as before, but the $item is passed by reference. This is the big difference, since we are not editing the $item we want to remove it from the parent array
I ran each of these loops 5000 times and measured the total time that took. This was to insure the time between results was big enough to exclude the randomness (at least enough) The test code I ran
5.6122910976414sec Loop: foreach traditional
6.0467801094055sec Loop: foreach unset key
7.7878839969635sec Loop: foreach traditional pass by reference
7.0686309337616sec Loop: foreach unset key pass by reference
8.6388339996338sec Loop: for
The traditional foreach I’ve been using for years turned out to be the fastest. Research hours well spend ?
Bonus edit array item
As said before most examples use editing a array. So I also ran that scenario. Test code I upped the loops from 5000 runs to 7500 because the difference was so small. And still it’s close.
Anonymous functions have been around for a long time. And since WordPress now supports php 5.6 it can be safely used. And appears to be allowed?
Personally I’m not a fan of anonymous functions in combination with WordPress actions and filters. My main concern is you can’t remove them once registered. How ever today I found a use case which was very usefull in combination with the use
My example:
<?php
/* Template name: some-template */
// Gather all data
$condition_for_title = true;
$h1_title_override = 'very heavy and complicated check';
// the H1 also needed as the <title>
add_filter( 'pre_get_document_title', function( $title ) use ($h1_title_override, $condition_for_title) {
if ($condition_for_title) {
return $h1_title_override;
}
return $title;
}, 20, 1 );
get_header();
// start body
?>
<h1><?php echo $h1_title_override ?>
Here I pass 2 variables h1_title_override and $condition_for_title which are created outside the function. In my case these where quite complicated and heavy checks. Of course I could put those in a function and cache the result. And call that check in the filter function. But still I need to check the current template before doing the function.
More traditional Example:
in functions.php
<?php
function complicated_check() {
// Gather all data
$condition_for_title = true;
$h1_title_override = 'very heavy and complicated check';
return [
'condition_for_title' => $condition_for_title,
'h1_title_override' => $h1_title_override,
];
}
function title_exception_for_template( $title ) {
if ( ! is_page_template('clean-template.php')) {
return $title;
}
$template_data = complicated_check();
if ( $template_data['condition_for_title'] ) {
return $template_data['h1_title_override'];
}
return $title;
}
add_filter( 'pre_get_document_title', 'title_exception_for_template', 20, 1 );
Both these approaches do the same thing. But the more traditional way is a lot more code. Although it has cleaner template. I probably won’t use this much. If the anonymous function was more complicated it will get hard to read.
But for this case I think it was neat that I could use this little feature.
Only useful for simple onelines. You’re very likely to be better of putting code in a php file and run that script like:
php ./helloworld.php
Run PHP with WordPress loaded.
Of course your good old friend wp-cli can help. It can run code with wp fully loaded. So if you add things in the init action or even after the wp_loaded, those plugin/theme functions, posttypes and such are all available.
First off the plain php code execution, with wp eval
In this guide we will install php 7.4 and do very basic tweaks. This should also work with php8 and older versions.
In this guide we will install php 7.4 and do very basic tweaks
Note: this post call also be used to install php7.0, php7.1, php7.2 or php7.3, just change every reference to 7.x. Only php7.3 and higher are still supported This guide should also work for installing php8.0 but I haven’t tested this yet.
Check if you can install php7.4
To check if php7.4 is available run: sudo apt install --dry-run php7.4 If you get an error continue, if you don’t get an error continue to actual install php
As the php version is not available We are going to create a new source for php. We do this with the following 3 commands.
When done check it with php -v it should show a php 7.4.0 or higher. Now we need to add a few fpm things for nginx to work properly. Create a extra config file sudo nano /etc/php/7.4/fpm/conf.d/90-pi-custom.ini. And add:
<?php
interface InterfaceTest {
function GetSingleEntity(): Entity;
function GetEntitySet() : Entity[];
}
GetEntitySet should return a array containing Entities. But this kind of syntax is not allowed. You could just change it to only return an array, but the forcing of the class is the most powerful. The best is to create a wrapper class for the entities, best would be to use an Iterator.
I’m a big fan of xdebug I’ve been using it for years to dig into scripts. But I’ve only used it on websites. And as I’m dipping my toes into wp-cli the need for command line debugging is increasing.