As vendors such as HP, IBM, and Sun jumped on the Unix bandwagon, they all sought to add differentiating features to their versions of the OS that gave them a competitive advantage of the others. After a while this led to the various Unix flavours being incompatible, so various specifications were drawn up that were designed to give all the versions common elements so that programs written for one could compile on the others.
One of these - arguably the most important - is the POSIX specification, which most modern OSes adhere to. Linux, Solaris, Mac OS X, OpenBSD, and even Windows all support the POSIX specification, and what this means to us is that as PHP programmers we can often take advantage of some of these standard function calls to enhance our script. Sadly, the Microsoft implementation of POSIX in Windows isn't good enough to support the POSIX functions that PHP exposes, which means if you want to use POSIX you must be using some form of Unix.
POSIX itself stands for "Portable Operating Systems Interface" (POSI), although because Unix was the majority OS at the time, the "X" was hooked on and has survived ever since. PHP's implementation of the POSIX functions are essentially just wrappers around their native C calls: if you know how to use them in C, you know how to use them in PHP. There are actually quite a few supported (over thirty at the time of writing) but many are too simple or weird to worry about learning. Here's the list I consider important:
string posix_getlogin ( void )
int posix_getpid ( void )
array posix_getpwnam ( string username)
bool posix_kill ( int pid, int sig)
array posix_times ( void )
array posix_uname ( void )
Each of those do quite different things, but I want to briefly summarise their actions before we go onto examples. First up, posix_getlogin() returns the username of the person who ran the script. Next up, posix_getpid() returns the process ID number of the current PHP process. The posix_getpwnam() function returns information about the user specified in the parameter. Next, the posix_kill() function lets you send signals to a process, which essentially works like a simple messaging system. The posix_times() function is a hidden gem, and returns usage information about the current PHP process: how much CPU time it has used, etc. Finally, posix_uname() returns an array of information about the system running the script.
Three of those functions (posix_getpwnam(), posix_times(), and posix_name()) return arrays of data - running the return values through var_dump() reveals the values in those arrays neatly:
<?php
var_dump(posix_getpwnam("hudzilla"));
var_dump(posix_times());
var_dump(posix_uname());
?>
The output of that script will be different from machine to machine, but here's what I get:
array(7) {["name"]=>string(4) "hudzilla" ["passwd"]=> string(1) "x" ["uid"]=> int(501) ["gid"]=> int(501) ["gecos"]=> string(11) "Paul Hudson" ["dir"]=> string(10) "/home/hudzilla" ["shell"]=> string(9) "/bin/bash" }
array(5) { ["ticks"]=> int(448754096) ["utime"]=> int(0) ["stime"]=> int(0) ["cutime"]=> int(0) ["cstime"]=> int(0) }
array(5) { ["sysname"]=> string(5) "Linux" ["nodename"]=> string(7) "carmen" ["release"]=> string(10) "2.6.7" ["version"]=> string(30) "#1 Tue August 9 22:26:13 BST 2004" ["machine"]=> string(4) "i686" }
Most of those will be obvious, but let me explain the rest: "passwd" is an X because I'm using shadow passwords, "ticks" is the number of clock ticks since I last rebooted, "utime" and "stime" are the amount of user and system time used by the current PHP process, and "cutime" and "cstime" are the amount of user and system time used by the current PHP process and any children. All of the output of posix_uname() can be achieved by passing various switches to the "uname" program.
User IDs, group IDs, and particularly passwords are generally best not revealed to the world, so please be careful with these functions.
This code block demonstrates how to use the other three functions:
<?php
$login = posix_getlogin();
$mypid = posix_getpid();
$rand = rand(1,2);
if ($rand == 2) {
echo "Process $mypid owned by $login has been selected for death!\n";
posix_kill($mypid, SIGKILL);
} else {
echo "Process $mypid owned by $login lives on!\n";
}
?>
That little script grabs the username of the person who ran the script, along with the PID of the PHP process running the script, then randomly kills the process 50% of the time. If you find you get a message like "Process 2071 owned by lives on!", which has a blank where the username should be, you're probably running it from a virtual console running inside X. These consoles don't register themselves with utmp (a binary file that usually resides in /var/run), which means login information won't be available. Running the same script from a terminal outside of X should cure the problem.
Want to learn PHP 7?
Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!
If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!
Next chapter: Error handling >>
Previous chapter: Piping between processes
Jump to:
Home: Table of Contents
Copyright ©2015 Paul Hudson. Follow me: @twostraws.