LeafPHP
One thing I have not done much with PHP is looking at different frameworks. For many other languages such as Python and Java I have used quite some frameworks such as Netty, Twisted, Flask, Quart, and CherryPy. For PHP however I have not seen many at all that I have really looked into. For that reason I am looking into one that looks good called LeafPHP.
The first thing to notice about LeafPHP is that there is a router there and a hello world app might look like this
index.php
<?php
require '/home/pi/.config/composer/vendor/autoload.php';
app()->get('/', function () {
response()->json([
'message' => 'Welcome!'
]);
});
app()->run();
And what to also note is that it redirects all requests in the directory and down unless there already is a file or folder using a .htaccess
file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
In order to stat using LeafPHP is quite simple. Just first make sure to install composer which can be done using
sudo apt install composer
but you might also want to install apache with php which can be done using
sudo apt install libapache2-mod-php
which will automatically install apache and the latest php as a module.
Now we can run a certain composer command that is
composer global require leafs/cli
which will install a command line tool that you can use to install what is needed for an app and get an example project running using the command
leaf create
keep in mind the command might not end up in path but it will end up somewhere like ~/.config/composer/vendor/bin/leaf
so you can add ~/.config/composer/vendor/bin
to $PATH
to be able to run it with ~ expanded of course which is just a shell symbol to get the home directory for your current user.
Running that command will give you a file that looks like this
index.php
<?php
require __DIR__ . '/vendor/autoload.php';
app()->get('/', function () {
response()->page('./welcome.html');
});
app()->run();
and as you can see it will read a HTML file that looks like the image below if you do not bother running it yourself.
In order to get this to show you need to either run something like leaf serve
which will start a server accessible from localhost only or better use the apache php combination and have the app somewhere in the webroot or any subdirectory.
Now we are going to look at features. I have worked in the past in Flask and Quart which also has routing and as seen in the examples above it has emitting of HTML files and JSON documents.
# Emit HTML page
response()->page('./welcome.html');
# Emit JSON
response()->json([
'message' => 'Welcome!'
]);
Just like similar frameworks it also has some handling for special routes to insert variables and such.
app()->get('/page/{page}', function ($page) {
response()->json(['message' => "This is page $page"]);
});
# Path /1 will return the response {"message":"This is page 1"}
Which is quite elegant and having a single point handle all requests makes it easier to read the code compared to having many PHP files and makes it easy to add things like headers in one place. We need to however look at a lot of basic things that is usually done and how LeafPHP would do it.
# Handle post request taking a query string parameter
app()->post('/param', function () {
$param = request()->get('parameter');
response()->json(['message' => "The parameter is $param"]);
});
# Responds {"message":"The parameter is 1"} if the URL has a query string like ?parameter=1
# It will return {"message":"The parameter is "} if nothing is set
# Send plain text containing the accept header
app()->get('/headers', function () {
$accept = request()->headers('Accept');
response()->plain("mew the accept header is $accept");
});
# Will return something like
# mew the accept header is text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
# Globally set a header
Leaf\Http\Headers::set(['Access-Control-Allow-Origin' => '*']);
# Header will now always have the following set on every path
# Access-Control-Allow-Origin: *
# Send raw HTML as a string
app()->get('/html', function () {
response()->markup('This is some raw html as a string<br />Meow');
});
# Will return
# This is some raw html as a string
# Meow
# Take the raw post body
app()->post('/body', function () {
$body = request()->body();
response()->json($body);
});
# curl --header 'Content-Type: application/json' -d '{"a":[1,2,3]}' -X POST
# returns {"a":[1,2,3]}
# curl -d 'urlencodedparampostbody=yep' -X POST
# returns {"urlencodedparampostbody":"yep"}
# curl --header 'Content-Type: text/plain' -d 'setwitgujh4weitg=1' -X POST
# return ["setwitgujh4weitg=1"] but unsure why the array is there
So one thing that is interesting is that PHP is considered a really bad language but using frameworks like this will make it much easier to write certain things.
One thing that is convenient is regex path matching that looks like this and is harder to do without any form of framework.
# Regex path matching
app()->get('/(meo?w)', function ($meow) {
response()->plain($meow);
});
# returns either meow or mew depending on what path you used
# Alphanumeric string 1 to 10 characters then one lowercase onle exactly 64 characters (A sha256 hash)
app()->get('/yes/([0-9a-zA-Z]{1,10})/([a-z0-9]{64})', function ($channel, $hash) {
response()->plain("$channel $hash");
});
# Path /yes/B00ba/30f7d6673d054fc66b6984765574e44330c7aa0dede4fb64b0c502776a47bb1c
# Returns B00ba 30f7d6673d054fc66b6984765574e44330c7aa0dede4fb64b0c502776a47bb1c
# Alphanumeric strings separated by comma
app()->get('/tags/([0-9a-z,]+)', function ($tags) {
$alltags = explode(',', $tags);
response()->json($alltags);
});
# Path /tags/salads,meows,cats,dogs,foxes,stones
# Returns ["salads","meows","cats","dogs","foxes","stones"]
I will perhaps use this in another project as it is actually useful and a lot of useful things could be done if the quirks can be worked out and such. One example is when installing I ran into an issue where if a certain PHP extension was missing it would try to install an earlier version of LeafPHP but still the latest addon libraries which would make it try to add a newly added function called getStatic
and crash but I got messaged by the creator and it was solved.
So yeah this is an interesting framework that I will look more into but I do rate it very high as it is very good except one thing that is some HTML error system that I have not managed to turn off and sometimes I would like to get JSON error messages when using cURL as the HTML response on error is extremely large.
I also have some other things to review such as SlimeVR full body VR tracking that I got sent free of charge to review and such.
*Mweeoops*
By ellietheyeen 30 September 2024 Permalink Tags: apache framework leafphp php review