Enough of the lyrics, let’s move on to the code. PHP is not the best language for building system applications. For example, it does not have a function to get system disks. But when did such a fact stopped us? We’ll use iterating through the entire alphabet and checking if the directory exists in Windows. The function reads the /etc/fstab
file line by line in Linux, splits each line on spaces to get the columns, and checks for the existence of a directory:
function fs_get_roots() {
static $roots = null;
if ($roots === null) {
if (strncasecmp(PHP_OS, 'WIN', 3) === 0) {
$driveLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
for ($i = 0; $i < strlen($driveLetters); $i++) {
$curDrive = $driveLetters[$i].':\\';
if (is_dir($curDrive)) {
$roots[] = $curDrive;
}
}
} else {
foreach (file('/etc/fstab') as $line) {
if ($line[0] != '#') {
$line = str_replace('\t', ' ', $line);
do
$line = str_replace(' ', ' ', $line, $count);
while($count);
$rows = explode(' ', $line);
if (count($rows) && is_dir($rows[1])) {
$roots[] = $rows[1];
}
}
}
}
}
return $roots;
}
The roots of the file system are cached in the $roots
static variable. That is, if you call this function several times when generating a page then the next call will work very quickly since the disk will not be rescanned.
On the one hand, the code turned out not very beautiful. Direct parsing of system files is used in Linux to write low-level utilities. For example, some of the implementations of df
may really read /etc/fstab
. Such code is normal for programs written in C. But not for high-level programming languages. Guessing the disk name alphabetically is generally a malicious hack. For example, if a disc is inserted into a DVD drive, it will spin up every time it is accessed…
On the other hand, the result has been achieved. PHP was created for generating web pages. But if you want, you can even write system software on it.
I use the example of a progress bar on the bootstrap as a view. Here you have Bootstrap itself, HTML5, and also JQuery included for some reason.
One of the desires was to have a localization system built into the application. So that Russian-speaking users see the application in Russian, Czechs - in Czech, etc. The localization system will be made in jQuery. Well, you need to use it at least for something:
$(document).ready(function() {
var userLang = (navigator.language || navigator.userLanguage)
?.substring(0, 2)?.toLowerCase();
$('[data-' + userLang + ']').each(function(element) {
var localized = $(this).data(userLang);
$(this).text(localized);
});
});
The userLang
variable stores 2 letters of the user’s browser language. For example, ru
. Next, iterate through all the tags that have the data-ru
attribute. Further, the text of the current element is simply set to the obtained from the data.
An example of HTML markup for using such a localization system:
<h2 data-ru="Системный диск" data-cz="Systémový disk">System Drive</h2>
The main disadvantage of such a localization system is visible here - the code becomes very overloaded, and all users always download data for all languages. Such localization is suitable if the project needs to translate just a few short phrases into a small number of languages. So: good for example only.
PH7 is an alternative PHP implementation for embedded systems. PH7 was developed to revive the UI in routers, where raw HTML codes were embedded directly into the firmware written in C.
PH7 is free for open source projects. The main advantage is the extremely small size - I was able to compile ph7-cgi
into an application with a size of about 300 kilobytes.
The number of disadvantages of the PH7 is slightly bigger than the advantages. The main disadvantages of PH7:
For example, the functions disk_total_space
and disk_free_space
always return a null value in Linux (visible on the screenshot). I did not make an alternative implementation of these functions (for example, through the parsing of the df
output) since this is not the purpose of this publication. And it is problematic to call third-party utilities since there is a null value instead of the exec
function.
In general, PHP in this publication is more of an element of humor than real benefit.
The short solution has already been written above. Let’s look at the client-server part: CivetWeb + WebView.
CivetWeb (formerly Mongoose before the license change) is the de facto standard when you need to quickly distribute something over HTTP on the desktop. It’s not a production solution like Nginx - my local server doesn’t need to serve millions of files per second. And hundreds of evil hackers won’t try to crack it. And a very big question is whether it will ever be allowed into the external network.
WebView is just the ability to embed a system browser in your application. It will be Edge for Windows, it will be GTK WebKit for Linux, it will be Cocoa or WebKit for Mac. That is, some modern browser that supports HTML5, CSS3, and JavaScript well. At the same time, the resulting application will not grow to hundreds of megabytes, since the engine will not be built directly into the resulting application.
Both of these technologies look good to me. The only thing is, I never found a single project that combines them. So I had to make my own: CivetWebView - https://github.com/DeXP/CivetWebView
Basically, CivetWebView is a combination of code from two examples: CivetWeb and WebView. At the moment, the project is more likely at the prototype stage - only the functionality I need has been implemented. Many things are simply set as constants in the code.
An example of project improvements: the ability to load values from a configuration file, support for full-screen mode, and the ability to dynamically set the window title and its size.
A complete Win32 application is 1.53MB. The largest component is CivetWebView, which takes up almost a megabyte. Next comes the PHP interpreter at 282 kilobytes. Rounding out the top three are Bootstrap and JQuery, which take up a total of 274 kilobytes (excluding debug map files). The application code itself (PHP + HTML + CSS) takes about 5 kilobytes.
Source codes and archives with binaries can be downloaded from Github: https://github.com/DeXP/CivetWebView-PH7-Example
Everything except PH7 is licensed under “yes, do what you want with it, we don’t care at all”. That is, if you exclude PH7 from the bundle, then you can make commercial applications. Can someone explain to me why? :-)
Initially, I did not have the task of creating a spherical GUI project in a vacuum. There was a project for an online visual novel interpreter from the DS console - VNDS-Online. And I immediately wanted to be able to run these games not only on some site but also locally on my computer. Or on some other device.
vnds-online cannot work without a back end. At a minimum, you should be able to get a list of available games. This functionality was not too difficult to rewrite in LUA.
In addition, I wanted to give the opportunity to run games with a simple double click on the EXE file. So that even the most web development unrelated person could play.
As a result, the project turned out to be compact due to the fact that most of the code implies execution in the browser. Which is already installed in the system, well debugged and optimized. In general, thank you very much VaYurik for a wonderful engine.
However, vnds-online
also has room for improvements. For example, the engine clearly needs the ability to be localized. I would also like the ability to adapt the picture to modern wide screens. Well, debugging existing bugs, of course.
Instead of a conclusion, I want to ask the community two questions:
vnds-online
at all?Other Articles
ARTICLES
articles linux windows gui tiny php jquery bootstrap desktop web
Leave a comment