# PHP for system administration



## bsaidus (Nov 11, 2014)

Hello.

I would like to know your opinion about using PHP for system administration purposes. 

Thanks.


----------



## Deever (Nov 11, 2014)

I have the same opinion about PHP for using system administration as I have for web development. This means I use awk/sed/zsh/Python for system administration.


----------



## SirDice (Nov 12, 2014)

Why install something as "heavy" as PHP to do this? Unless you want to create a web GUI use the shell as much as possible. Anything else would require several ports or packages to be installed (which could all break leaving you with broken tools).


----------



## kpa (Nov 12, 2014)

My vote goes to Python allthough I've been doing most of my recent script programming in pure /bin/sh (combined with the usual UNIX tools) due to the simple nature of the scripts. If I'd had to implement something more complex now I would use Python without a second thought.


----------



## bsaidus (Nov 12, 2014)

SirDice said:


> Why install something as "heavy" as PHP to do this? Unless you want to create a web GUI use the shell as much as possible. Anything else would require several ports or packages to be installed (which could all break leaving you with broken tools).



I think PHP do_es_ not take much space. So what shell do you preconize advise for that task??


----------



## SirDice (Nov 12, 2014)

bsaidus said:


> So what shell do you advise for that task?


In that case there's really only one option, /bin/sh.


----------



## Uniballer (Nov 12, 2014)

bsaidus said:


> I would like to know your opinion about using PHP for system administration purposes.



I see this kind of junk in my logs every few hours:

```
61.185.140.144 - - [12/Nov/2014:06:55:04 -0500] "GET /pupu/pup/pu.php HTTP/1.1" 404 213
61.185.140.144 - - [12/Nov/2014:06:55:08 -0500] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 226
61.185.140.144 - - [12/Nov/2014:06:55:08 -0500] "GET /pma/scripts/setup.php HTTP/1.1" 404 219
61.185.140.144 - - [12/Nov/2014:06:55:12 -0500] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 223
```
A bunch of people must have installed security holes along with their PHP administration tools, otherwise the script kiddies wouldn't bother to probe for them.


----------



## amitabh (Nov 12, 2014)

While most of those responding here have far more experience than me, I do use PHP to a large extent to manage my FreeBSD servers. Partly because most of my servers already have PHP installed on them. For the rest where it is not required like Database/VOIP servers, I just use the base PHP port/package, without any extensions, for managing the servers.


----------



## bsaidus (Nov 13, 2014)

amitabh said:


> While most of those responding here have far more experience than me, I do use PHP to a large extent to manage my FreeBSD servers. Partly because most of my servers already have PHP installed in them. For the rest where it is not required like Database/VOIP servers, I just use the base PHP port/package, without any extensions, for managing the servers.


Me too_!_


----------



## Carpetsmoker (Nov 13, 2014)

One obvious problem with PHP is that you can't reliably call external binaries; the "best" way is to use proc_open(), but that function has all sorts of problems and is difficult to use.

Indeed, much of the standard library has problems; take reading files for example, this is one of the most basic operations you can do, but PHP does not properly implement this.

The only function you have is fopen() (file_get_contents() etc. are all wrappers), this works pretty much the same as fopen() in C, with some dubious enhancements (like stream wrappers, which is a tale for another time). The problems start when there is an error; fopen() just returns False, and emits one of those magic uncatchable E_WARNING or E_ERROR errors; and there is no way to figure out what went wrong. In C, you can use the errno variable to check what went wrong, for example, the EEXISTS indicates the filename already exists, EACCESS indicates you don't have permission, ELOOP indicated there are too many symlinks, and so forth (there are many more). This is _very_ useful, for example, for an ENAMETOOLONG, you could trim the pathname and try again, for EEXISTS, you could try again with a different filename, etc. You can do something sane, rather than just quit and say "unable to proceed". In fact, for some things, this is even _required_, there is no way to make a safe temporary file _without_ this feature (the default functions in PHP for that are also inadequate, see this page).

There is no way to do this in PHP, other than "silence" the error with the @ operator, use error_get_last(), and do a string search on that. This is so ugly that I would never use it, the error might change in the future, and is even locale-independent (e.g. French locale gets French errors). You do need the @ + error_get_last() "trick" to present an error to the user, though; or install your own error handler, the default is to just quit the interpreter (yikes) or continue after an error (even more yikes).

There are some functions that get the errno for specific modules (curl_errno(), posix_errno()), but those only work for the functions from that module, not for fopen() (for example).

Now, contrast this with some other popular high-level languages:

In Ruby, you get an exception which is mapped to the C errno variable (e.g. Errno::EEXISTS). This is arguably not perfect, since some errno values are defined in POSIX, not all of them are, and Linux/BSD/etc. implement some OS-specific errno values; but for most things, it works okay. This is how it looks:

```
begin
  File.open '/etc/passwd', 'w'
rescue Errno::EACCESS
  puts 'Access denied'
  exit 1
  # Or maybe ask user for different filename and try again? Or maybe execute myself again with sudo? Or maybe try a different filename?
end
```

In Python, there is more abstraction, and you might get a FileNotFoundError or PermissionError, and it's even flexible enough to get the C errno variable; the code looks similar to the Ruby code, except it's less OS-dependent and arguably more readable:

```
try:
  open('/etc/passwd', 'w')
except PermissionError:
  print('Access denied')
  sys.exit(1)
  # Or maybe ask user for different filename and try again? Or maybe execute myself again with sudo? Or maybe try a different filename?
```

There are many more examples of basic functionality that's either incomplete, or downright broken. I'm not going to list them all, and hope the fopen() examples convinces you that PHP is not suitable for reliable and robust systems programming. If C has features that your "high-level" programming language does not have, then you have FAILED.


----------

