PHP & Web Development Blogs

Search Results For: class
Showing 26 to 30 of 31 blog articles.
21269 views · 5 years ago
Making Charts and Graphs using Laravel

Installing composer

Composer is a package management tool for PHP. Laravel requires composer for installation. We can download composer from https://getcomposer.org/download/

After installation that you can test whether composer installed or not by command
composer

Installing Laravel

The current stable version of laravel is laravel 5.6. We can install laravel package with three ways.

In command prompt or terminal by running composer global require "laravel/installer" and then Laravel new

or

We can create the project with Composer by running composer create-project --prefer-dist laravel/laravel

or

Directly clone from github
git clone https://github.com/laravel/laravel/tree/master and after that composer update

Laravel local development server

Run the below command in command prompt or terminal
PHP artisan serve


Above command will start to local development servehttp://localhost:8000 or if you want to change default port:

php artisan serve --port 


Generating charts and graphs

We are using consoletvs package for generating charts. So for installation we can first move inside to our project using command prompt or terminal. We are following the below steps to install

Step 1:

First we need to install ConsoleTVs/Charts composer package inside our laravel project.
composer require consoletvs/charts


Step 2:

After successfully installation of above package, open app/config.php and add service provider.
In config/app.php


'providers' => [
....
ConsoleTVs\Charts\ChartsServiceProvider::class,
],


After the service provider we need to add alias
'aliases' => [
....
'Charts' => ConsoleTVs\Charts\Facades\Charts::class,
]



Step 3

We need to configure of database for application. We can configure in either .env file or config/database.php file.


Step 4

We can migrate our default tables that is user. We can find the table in database/migration folder.

Step 5

We can generate dummy records for demo in users table. For creating dummy records, we need to run the below command in command prompt or terminal
php artisan tinker>>> factory(App\User::class, 20)->create();

the above command will create a set of 20 records.

If we need to add more records we need to run the above command or we can increase the count as much as we want. For example
php artisan tinker>>> factory(App\User::class, 2000)->create();


Step 6Creating controller

For creating controller we need to run below command in terminal or command prompt
php artisan make controller:<controller_name>


Step 7Adding the routes

We can add the routes for navigating our application. You can find routes file inside routes folder. Before 5.4 we can find routes.php file itself, now its web.php. If you are using laravel 5.2 routes.php will inside app/http folder.

So inside web.php:

Route::get('create-chart/{type}','ChartController@makeChart');


Here type will be the parameter we are passing and it will focus to makeChart() function inside chartcontroller

Step 8

Import charts to controller, for that in the namespace section add:

Use charts;


Step 9

We can put the below code into chartController

public function makeChart($type)
{
switch ($type) {
case 'bar':
$users = User::where(DB::raw("(DATE_FORMAT(created_at,'%Y'))"),date('Y'))
->get();
$chart = Charts::database($users, 'bar', 'highcharts')
->title("Monthly new Register Users")
->elementLabel("Total Users")
->dimensions(1000, 500)
->responsive(true)
->groupByMonth(date('Y'), true);
break;
case 'pie':
$chart = Charts::create('pie', 'highcharts')
->title('HDTuto.com Laravel Pie Chart')
->labels(['Codeigniter', 'Laravel', 'PHP'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'donut':
$chart = Charts::create('donut', 'highcharts')
->title('HDTuto.com Laravel Donut Chart')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'line':
$chart = Charts::create('line', 'highcharts')
->title('HDTuto.com Laravel Line Chart')
->elementLabel('HDTuto.com Laravel Line Chart Lable')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'area':
$chart = Charts::create('area', 'highcharts')
->title('HDTuto.com Laravel Area Chart')
->elementLabel('HDTuto.com Laravel Line Chart label')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'geo':
$chart = Charts::create('geo', 'highcharts')
->title('HDTuto.com Laravel GEO Chart')
->elementLabel('HDTuto.com Laravel GEO Chart label')
->labels(['ES', 'FR', 'RU'])
->colors(['#3D3D3D', '#985689'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
default:
break;
}
return view('chart', compact('chart'));
}


Step 10

Create a blade file. Blade is the view file used inside the laravel. You can add new blade file with any name with an extension of .blade.php
Here we are creating chart.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Charts</title>
{!! Charts::styles() !!}
</head>
<body>

<div class="app">
<center>
{!! $chart->html() !!}
</center>
</div>

{!! Charts::scripts() !!}
{!! $chart->script() !!}
</body>
</html>


Step 11

We can run our laravel application in local development server by php artisan serve command:

http://localhost:8000/create-chart/bar
http://localhost:8000/create-chart/pie
http://localhost:8000/create-chart/donut
http://localhost:8000/create-chart/line
http://localhost:8000/create-chart/area
http://localhost:8000/create-chart/geo



In the above example we was creating line chart, geo chart, bar chart, pie chart, donut chart, line chart and area chart. We can also create gauge chart, progressbar chart, areaspline chart, scatter chart, percentage chart etc using consoletvs charts composer package.

There are a lot of jQuery libraries also available like amcharts, chartjs, highcharts, google, material, chartist, fusioncharts, morris, plottablejs etc. However, using this plugin we can easily create charts without having to use jQuery, another advantage to building it in with Laravel.
12760 views · 5 years ago
Creating a PHP Daemon Service

What is a Daemon?

The term daemon was coined by the programmers of Project MAC at MIT. It is inspired on Maxwell's demon in charge of sorting molecules in the background. The UNIX systems adopted this terminology for daemon programs.

It also refers to a character from Greek mythology that performs the tasks for which the gods do not want to take. As stated in the "Reference System Administrator UNIX", in ancient Greece, the concept of "personal daemon" was, in part, comparable to the modern concept of "guardian angel." BSD family of operating systems use the image as a demon's logo.

Daemons are usually started at machine boot time. In the technical sense, a demon is considered a process that does not have a controlling terminal, and accordingly there is no user interface. Most often, the ancestor process of the deamon is init - process root on UNIX, although many daemons run from special rcd scripts started from a terminal console.

Richard Stevenson describes the following steps for writing daemons:
    . Resetting the file mode creation mask to 0 function umask(), to mask some bits of access rights from the starting process.
    . Cause fork() and finish the parent process. This is done so that if the process was launched as a group, the shell believes that the group finished at the same time, the child inherits the process group ID of the parent and gets its own process ID. This ensures that it will not become process group leader.
    . Create a new session by calling setsid(). The process becomes a leader of the new session, the leader of a new group of processes and loses the control of the terminal.
    . Make the root directory of the current working directory as the current directory will be mounted.
    . Close all file descriptors.
    . Make redirect descriptors 0,1 and 2 (STDIN, STDOUT and STDERR) to /dev/null or files /var/log/project_name.out because some standard library functions use these descriptors.
    . Record the pid (process ID number) in the pid-file: /var/run/projectname.pid.
    . Correctly process the signals and SigTerm SigHup: end with the destruction of all child processes and pid - files and / or re-configuration.

How to Create Daemons in PHP

To create demons in PHP you need to use the extensions pcntl and posix. To implement the fast communication withing daemon scripts it is recommended to use the extension libevent for asynchronous I/O.

Lets take a closer look at the code to start a daemon:
umask(0);
$pid = pcntl_fork(); 
if ($pid < 0) {
print('fork failed');
exit 1;
}


After a fork, the execution of the program works as if there are two branches of the code, one for the parent process and the second for the child process. What distinguishes these two processes is the result value returned the fork() function call. The parent process ID receives the newly created process number and the child process receives a 0.
if ($pid > 0) { echo "daemon process started
";
exit; }

$sid = posix_setsid(); if ($sid < 0) {
exit 2;
}

chdir('/'); file_put_contents($pidFilename, getmypid() );
run_process();


The implementation of step 5 "to close all file descriptors" can be done in two ways. Well, closing all file descriptors is difficult to implement in PHP. You just need to open any file descriptors before fork(). Second, you can override the standard output to an error log file using init_set() or use buffering using ob_start() to a variable and store it in log file:
ob_start();
var_dump($some_object);
$content = ob_get_clean();
fwrite($fd_log, $content); 


Typically, ob_start() is the start of the daemon life cycle and ob_get_clean() and fwrite() calls are the end. However, you can directly override STDIN, STDOUT and STDERR:
ini_set('error_log', $logDir.'/error.log');
fclose(STDIN); 
fclose(STDOUT);
fclose(STDERR);
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen($logDir.'/application.log', 'ab');
$STDERR = fopen($logDir.'/application.error.log', 'ab');


Now, our process is disconnected from the terminal and the standard output is redirected to a log file.

Handling Signals

Signal processing is carried out with the handlers that you can use either via the library pcntl (pcntl_signal_dispatch()), or by using libevent. In the first case, you must define a signal handler:
function sig_handler($signo)
{
global $fd_log;
switch ($signo) {
case SIGTERM:
fclose($fd_log); unlink($pidfile); exit;
break;
case SIGHUP:
init_data(); break;
default:
}
}

pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");


Note that signals are only processed when the process is in an active mode. Signals received when the process is waiting for input or in sleep mode will not be processed. Use the wait function pcntl_signal_dispatch(). We can ignore the signal using flag SIG_IGN: pcntl_signal(SIGHUP, SIG_IGN); Or, if necessary, restore the signal handler using the flag SIG_DFL, which was previously installed by default: pcntl_signal(SIGHUP, SIG_DFL);

Asynchronous I/O with Libevent

In the case you use blocking input / output signal processing is not applied. It is recommended to use the library libevent which provides non-blocking as input / output, processing signals, and timers. Libevent library provides a simple mechanism to start the callback functions for events on file descriptor: Write, Read, Timeout, Signal.

Initially, you have to declare one or more events with an handler (callback function) and attach them to the basic context of the events:
$base = event_base_new();
$event = event_new();
$errno = 0;
$errstr = '';
$socket = stream_socket_server("tcp://$IP:$port", $errno, $errstr);
stream_set_blocking($socket, 0); event_set($event, $socket, EV_READ | EV_PERSIST, 'onAccept', $base);


Function handlers 'onRead', 'onWrite', 'onError' must implement the processing logic. Data is written into the buffer, which is obtained in the non-blocking mode:
function onRead($buffer, $id)
{
while($read = event_buffer_read($buffer, 256)) {
var_dump($read);
}
}


The main event loop runs with the function event_base_loop($base);. With a few lines of code, you can exit the handler only by calling: event_base_loobreak(); or after the specified time (timeout) event_loop_exit();.

Error handling deals with failure Events:
function onError($buffer, $error, $id)
{
global $id, $buffers, $ctx_connections;
event_buffer_disable($buffers[$id], EV_READ | EV_WRITE);
event_buffer_free($buffers[$id]);
fclose($ctx_connections[$id]);
unset($buffers[$id], $ctx_connections[$id]);
}


It should be noted the following subtlety: Working with timers is only possible through the file descriptor. The example of official the documentation does not work. Here is an example of processing that runs at regular intervals.
$event2 = event_new();
$tmpfile = tmpfile();
event_set($event2, $tmpfile, 0, 'onTimer', $interval);
$res = event_base_set($event2, $base);
event_add($event2, 1000000 * $interval);


With this code we can have a working timer finishes only once. If we need a "permanent" Timer, using the function onTimer we need create a new event each time, and reassign it to process through a "period of time":
function onTimer($tmpfile, $flag, $interval)
{
$global $base, $event2;

if ($event2) {
event_delete($event2);
event_free($event2);
}

call_user_function(‘process_data’,$args);

$event2 = event_new();
event_set($event2, $tmpfile, 0, 'onTimer', $interval);
$res = event_base_set($event2, $base);
event_add($event2, 1000000 * $interval);
}


At the end of the daemon we must release all previously allocated resources:
event_delete($event);
event_free($event);
event_base_free($base);

event_base_set($event, $base);
event_add($event);


Also it should be noted that for the signal processing handler is set the flag EV_SIGNAL: event_set($event, SIGHUP, EV_SIGNAL, 'onSignal', $base);

If needed constant signal processing, it is necessary to set a flag EV_PERSIST. Here follows a handler for the event onAccept, which occurs when a new connection is a accepted on a file descriptor:
function onAccept($socket, $flag, $base) {
global $id, $buffers, $ctx_connections;
$id++;
$connection = stream_socket_accept($socket);
stream_set_blocking($connection, 0);
$buffer = event_buffer_new($connection, 'onRead', NULL, 'onError', $id);
event_buffer_base_set($buffer, $base);
event_buffer_timeout_set($buffer, 30, 30);
event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff); event_buffer_priority_set($buffer, 10); event_buffer_enable($buffer, EV_READ | EV_PERSIST); $ctx_connections[$id] = $connection;
$buffers[$id] = $buffer;
}


Monitoring a Daemon

It is good practice to develop the application so that it was possible to monitor the daemon process. Key indicators for monitoring are the number of items processed / requests in the time interval, the speed of processing with queries, the average time to process a single request or downtime.

With the help of these metrics can be understood workload of our demon, and if it does not cope with the load it gets, you can run another process in parallel, or for running multiple child processes.

To determine these variables need to check these features at regular intervals, such as once per second. For example downtime is calculated as the difference between the measurement interval and total time daemon.

Typically downtime is determined as a percentage of a measurement interval. For example, if in one second were executed 10 cycles with a total processing time of 50ms, the time will be 950ms or 95%.

Query performance wile be 10rps (request per second). Average processing time of one request: the ratio of the total time spent on processing requests to the number of requests processed, will be 5ms.

These characteristics, as well as additional features such as memory stack size queue, number of transactions, the average time to access the database, and so on.

An external monitor can be obtain data through a TCP connection or unix socket, usually in the format of Nagios or zabbix, depending on the monitoring system. To do this, the demon should use an additional system port.

As mentioned above, if one worker process can not handle the load, usually we run in parallel multiple processes. Starting a parallel process should be done by the parent master process that uses fork() to launch a series of child processes.

Why not run processes using exec() or system()? Because, as a rule, you must have direct control over the master and child processes. In this case, we can handle it via interaction signals. If you use the exec command or system, then launch the initial interpreter, and it has already started processes that are not direct descendants of the parent process.

Also, there is a misconception that you can make a demon process through command nohup. Yes, it is possible to issue a command: nohup php mydaemon.php -master >> /var/log/daemon.log 2 >> /var/log/daemon.error.log &

But, in this case, would be difficult to perform log rotation, as nohup "captures" file descriptors for STDOUT / STDERR and release them only at the end of the command, which may overload of the process or the entire server. Overload demon process may affect the integrity of data processing and possibly cause partial loss of some data.

Starting a Daemon

Starting the daemon must happen either automatically at boot time, or with the help of a "boot script."

All startup scripts are usually in the directory /etc/rc.d. The startup script in the directory service is made /etc/init.d/ . Run command start service myapp or start group /etc/init.d/myapp depending on the type of OS.

Here is a sample script text:
#! /bin/sh
#
$appdir = /usr/share/myapp/app.php
$parms = --master –proc=8 --daemon
export $appdir
export $parms
if [ ! -x appdir ]; then
exit 1
fi

if [ -x /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
fi

RETVAL=0

start () {
echo "Starting app"
daemon /usr/bin/php $appdir $parms
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mydaemon
echo
return $RETVAL
}

stop () {
echo -n "Stopping $prog: "
killproc /usr/bin/fetchmail
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/mydaemon
echo
return $RETVAL
}

case in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status /usr/bin/mydaemon
;;
*)
echo "Usage:
php
if (is_file('app.phar')) {
unlink('app.phar');
}
$phar = new Phar('app.phar', 0, 'app.phar');
$phar->compressFiles(Phar::GZ);
$phar->setSignatureAlgorithm (Phar::SHA1);
$files = array();
$files['bootstrap.php'] = './bootstrap.php';
$rd = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach($rd as $file){
if ($file->getFilename() != '..' && $file->getFilename() != '.' && $file->getFilename() != __FILE__) {
if ( $file->getPath() != './log'&& $file->getPath() != './script'&& $file->getPath() != '.')
$files[substr($file->getPath().DIRECTORY_SEPARATOR.$file->getFilename(),2)] =
$file->getPath().DIRECTORY_SEPARATOR.$file->getFilename();
}
}
if (isset($opt['version'])) {
$version = $opt['version'];
$file = "buildFromIterator(new ArrayIterator($files));
$phar->setStub($phar->createDefaultStub('bootstrap.php'));
$phar = null;
}
 {start|stop|restart|status}"
;;

RETVAL=$?
exit $RETVAL


Distributing Your PHP Daemon

To distribute a daemon it is better to pack it in a single phar archive module. The assembled module should include all the necessary PHP and .ini files.

Below is a sample build script:
#php app.phar
myDaemon version 0.1 Debug
usage:
--daemon – run as daemon
--debug – run in debug mode
--settings – print settings
--nofork – not run child processes
--check – check dependency modules
--master – run as master
--proc=[8] – run child processes


Additionally, it may be advisable to make a PEAR package as a standard unix-console utility that when run with no arguments prints its own usage instruction:
[NMD%%CODE%%]


Conclusion

Creating daemons in PHP it is not hard but to make them run correctly it is important to follow the steps described in this article.

Post a comment here if you have questions or comments on how to create daemon services in PHP.
7548 views · 5 years ago
Now that the Thanksgiving and Black Friday are left behind, we're all back at our desks, some of us having PHPStorm open for the whole day. In this post, I'll say a few words on this beautiful IDE, PHPUnit and XDebug.
You know that unit tests are essential, don't you? So do the PHPStorm developers. This industry-standard level IDE has tons of capabilities for integrating test frameworks and debuggers into your project. Even if you use VMs or containers to run your development environment, chances are they got you covered!

Blind Pew from Treasure Island

I often see even experienced PHP programmers debugging their code with var_dump(), which is obviously not the best way to do it. If you see the code for the first time, if you work with legacy code - step-by-step interactive debugging is the way to go. Sometimes it can save you hours of old school var_dumping.

As of unit tests, I often hear that it's good enough to run tests from the terminal. I even know a guy who runs watch phpunit /path/to/test while developing: this way the test is run every 2 seconds, you switch to the terminal whenever you want to see the latest results and that's it. However, there are certain advantages in running tests from the IDE. First, it's super-handy to launch a test method, test class or a whole folder with tests, just by pressing a hotkey. Second, the test results appear right there, in PHPStorm, with failures and their stack traces, every entry clickable and takes you directly to the file:line where a nasty thing happened. I also find the ability to run a debugger for a unit test, extremely attractive. Test fails, you click on a trace entry, get to a problematic line, place a break point, re-run the test in debug mode - and there you go.

For all those integrations, you will first need to setup the PHP interpreter for the project: Configuring PHP Development Environment. You will find both local and remote interpreter setups. "Local" is the PHP that you have on your workstation, the host machine. "Remote" can be pretty much everything: SSH if your Dev environment runs on a shared sandbox for all developers, docker or docker-compose if you run it using docker containers.

Next step - creating PHPUnit configuration. Go toSettings -> Languages and Frameworks -> PHP -> Test Frameworks. Follow this guide, it has much more information which will be more up-to-date than this post.Don't forget to set Path Mappings for your remote environments! That is, you probably have your project in, say, $HOME/projects/cool-project, but inside a docker or on a remote host it might be located at /app or /var/www, then you have to let PHPStorm know about this.

Once you're done with PHPUnit setup, you can finally run your tests! The default shortcut on my Linux machine isCtrl+Shift+F10 (shortcuts are usually different on Mac though). Place a cursor inside a test method, press the shotcut: PHPStorm will launch PHPUnit withthat particular test method! When the cursor in a scope of test class but not inside a test method - the whole test class will be run. And, you also can select a whole folder with tests, in the project tree and run it, ain't that cool?

A small tip for the docker-compose lovers. When I first set PHPStorm integration with docker-compose and ran the tests, I was quite surprised (unpleasantly) to see that myphp-fpm service that I was connecting to, is gone after the test process is finished. Took me some time to figure out that it's PHPStorm's expected behavior. It stops the target service after it's done testing. A workaround I started to use is as follows: I just add another service calledphpunit which uses a php-fpm or php-cli image, and is not needed by anything except unit testing in PHPStorm.

Now to debugging.


Debugging is like being the detective in a crime movie where you are also the murderer. Filipe Fortes a.k.a. @fortes


Obviously, your PHP interpreter in development environment will need a debugger extension in order for you to debug interactively. PHPStorm support the two most widely used options: XDebug and Zend Debugger. When using docker I usually make a separate Dockerfile for development, using production image as base, then add development tools,XDebug being the most important. Honestly, I've never usedZend Debugger, so have little to tell about its' nuances.

Got an extension? Go to Debugging Ultimate Guide! Debugger settings in PHPStorm are atSettings -> Languages and Frameworks -> PHP -> Debug. Most of the time you don't need to change them.Again, a note for docker-compose users. There is an XDebug setting that allow debugger to resolve the client (PHPStorm) IP address:xdebug.remoteconnect_back_. That's a disappointment but those will not work, at least with a default docker-compose setup. Thing is, all containers in a compose stack are running behind a network proxy provided by docker-compose. That is, the REMOTE_ADDR for all the containers will always be the IP of proxy. A workaround:

* disablexdebug.remoteconnect_back_;
* add.user.ini to the application root folder with the following contents:xdebug.remotehost = 192.168.X.X_ (your machine's IP address in the LAN). It's generally a good idea to exclude.user.ini from VCS control.

As a conclusion: if you still usevardump()_ to debug, stop living in the stone age, upgrade your knowledge and become more productive! If you don't write unit tests, start doing it. If your managers say it's a waste of time, tell them that it's coding without tests that is a waste of time. And, if you find this post of any use, or have an opinion, or a question - please do comment!
9214 views · 5 years ago
Type Arrays with Variadic Functions in PHP

It's a very common task to work with an array of values, each of the same type. Integers, strings, all kinds of objects etc. But PHP is still a weakly typed language, so it's hard to tell if an arbitrary array actually contains only values of a given type.
Of course, you can always use a class:
class IntArray {
private $values = [];
public function add(int $value) {
$this->values[] = $value;
}
}

Then, whenever you need an array of integers, you may write something like this:
class BatchProcessor
{
private $ids;
public function __construct(IntArray $ids) {
$this->ids = $ids;
}
}

Not bad. You'll need a class per type, though, and that may seem a bit of an overkill for such a simple task. Luckily, same result can be achieved differently, but with the same level of confidence in every value type:
class BatchProcessor
{
private $ids;
public function __construct(int ...$ids) {
$this->ids = $ids; }
}

Voila - no need for extra class! This approach uses the PHP 7's type hinting for scalar types, in conjunction with Variable length argument lists available since PHP 5.6. In fact, variable-length argument lists have been around since probably the very first version of the language, but in 5.6 they were revisited and got some nice syntactic sugar in form of "...", so you declare and call them as easy as this:
function func(...$args){...}
$args = [1, 2, 3];
func(...$args);

The approach can work with any type-hinting available in PHP, and I hope you find it somewhat useful! Comment, discuss share and ask questions - I'll be around.
4651 views · 5 years ago
PHP Basics

It's 2018, and you're a top-notch modern web developer, with a load of knowledge and tools right there at your disposal: Google and StackOverflow, debugger with a GUI, IDE with autocomplete, you name it. Occasionally, though, you still find yourself in a plain old text console on a remote server, or you have to do something without IDE, or there is no network connection... In such cases it might be helpful to feel comfortable in a simple terminal. In this post I'm going to list some switches for the PHP command that you can use to get information and some utilities.

Getting basic information about PHP


$ php -i
phpinfo()
PHP Version => 7.2.10-0ubuntu1

System => Linux awesome 4.18.0-10-generic #11-Ubuntu SMP Thu Oct 11 15:13:55 UTC 2018 x86_64
Build Date => Sep 13 2018 13:38:55
Server API => Command Line Interface
Virtual Directory Support => disabled
...


Full information about your PHP interpreter. Pipe the output to the Unix less command in order to get pagination and search: php -i | less. Type Q to exit the less shell. Some distros might lack less, in that case you may try php -i | more, which doesn't give you search but still has pagination.

Want a short summary of which PHP extensions you have? Just ask:

$ php -m
[PHP Modules]
calendar
Core
ctype
date
dom
ds
exif
...


More specific info about core and extensions' functions and classes


Full information about functions and classes provided by an extension:

$ php --re ds
Extension [ <persistent> extension #46 ds version 1.2.6 ] {

- Dependencies {
Dependency [ json (Required) ]
Dependency [ spl (Required) ]
}

- Classes [11] {
Interface [ <internal:ds> interface Ds\Hashable ] {

- Constants [0] {
}

- Static properties [0] {
}
...


Information on a specific class:

$ php --rc Ds\Vector
Class [ <internal:ds> <iterateable> final class Ds\Vector implements Ds\Sequence, Traversable, Countable, JsonSerializable, Ds\Collection ] {

- Constants [1] {
Constant [ public integer MIN_CAPACITY ] { 8 }
}

- Static properties [0] {
}
...


Same for a function:

$ php --rf fopen
Function [ <internal:standard> function fopen ] {

- Parameters [4] {
Parameter #0 [ <required> $filename ]
Parameter #1 [ <required> $mode ]
Parameter #2 [ <optional> $use_include_path ]
Parameter #3 [ <optional> $context ]
}
}


Utilities


Ever found yourself creating a dummy PHP file of just a few lines - only to be run once and then deleted? The -a switch might be what you're looking for:

$ php -a
Interactive mode enabled

php > var_dump(join(", ", [1, 2, 3]));
php shell code:1:
string(7) "1, 2, 3"
php >


It starts an interactive shell so you can type any PHP code and execute it straight away. Requires PHP to be compiled with readline support (most distros have that anyway).

Want a quick check for any parse/syntax errors in a PHP file? Use linter:

$ php -l test.php 
PHP Parse error: syntax error, unexpected 'array_shift' (T_STRING) in test.php on line 4
Errors parsing test.php


It has a web-server!


Yes! Just in case you missed it, as of PHP 5.4.0, the CLI SAPI provides a built-in web server. Want a quick look at a web page generated by an app? Here you go:

$ cd /my_application/document_root
$ php -S localhost:8000


Then open http://localhost:8000/ in your browser of choice and enjoy!

Hope you also have enjoyed this reading. Your feedback and questions are always appreciated!

SPONSORS