Softpanorama
(slightly skeptical) Open Source Software Educational Society

May the source be with you, but remember the KISS principle ;-)

Google   


Command Line PHP

Old News ;-)

Recommended Links

 

    Etc

 from PHP Using PHP from the command line - Manual

As of version 4.3.0, PHP supports a new SAPI type (Server Application Programming Interface) named CLI which means Command Line Interface. As the name implies, this SAPI type main focus is on developing shell (or desktop as well) applications with PHP.

There are quite a few differences between the CLI SAPI and other SAPIs which are explained in this chapter. It's worth mentioning that CLI and CGI are different SAPI's although they do share many of the same behaviors.

Since PHP 4.3.0 the option --enable-cli is on by default. You may use --disable-cli to disable it.

By default when executing make, both the CGI and CLI are built and placed as sapi/cgi/php and sapi/cli/php respectively, in your PHP source directory. You will note that both are named php. What happens during make install depends on your configure line. If a module SAPI is chosen during configure, such as apxs, or the --disable-cgi option is used, the CLI is copied to {PREFIX}/bin/php during make install otherwise the CGI is placed there. So, for example, if --with--apxs is in your configure line then the CLI is copied to {PREFIX}/bin/php during make install. If you want to override the installation of the CGI binary, use make install-cli after make install. Alternatively you can specify --disable-cgi in your configure line.

Note: Because both --enable-cli and --enable-cgi are enabled by default, simply having --enable-cli in your configure line does not necessarily mean the CLI will be copied as {PREFIX}/bin/php during make install.

Starting with PHP 4.3.0 the windows package distributes the CLI as php.exe in a separate folder named cli, so cli/php.exe . Starting with PHP 5, the CLI is distributed in the main folder, named php.exe. The CGI version is distributed as php-cgi.exe. As of PHP 5, a new php-win.exe file is distributed. This is equal to the CLI version, except that php-win doesn't output anything and thus provides no console (no "dos box" appears on the screen). This behavior is similar to php-gtk. You should configure with --enable-cli-win32.

What SAPI do I have?: From a shell, typing php -v will tell you whether php is CGI or CLI. See also the function php_sapi_name() and the constant PHP_SAPI.

Note: A Unix manual page was added in PHP 4.3.2. You may view this by typing man php in your shell environment.

Differences of the CLI SAPI compared to other SAPIs:

The list of command line options provided by the PHP binary can be queried anytime by running PHP with the -h switch:

Usage: php [options] [-f] <file> [--] [args...]
       php [options] -r <code> [--] [args...]
       php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
       php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
       php [options] -- [args...]
       php [options] -a

  -a               Run interactively
  -c <path>|<file> Look for php.ini file in this directory
  -n               No php.ini file will be used
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -f <file>        Parse <file>.
  -h               This help
  -i               PHP information
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -r <code>        Run PHP <code> without using script tags <?..?>
  -B <begin_code>  Run PHP <begin_code> before processing input lines
  -R <code>        Run PHP <code> for every input line
  -F <file>        Parse and execute <file> for every input line
  -E <end_code>    Run PHP <end_code> after processing all input lines
  -H               Hide any passed arguments from external tools.
  -s               Display colour syntax highlighted source.
  -v               Version number
  -w               Display source with stripped comments and whitespace.
  -z <file>        Load Zend extension <file>.

  args...          Arguments passed to script. Use -- args when first argument
                   starts with - or script is read from stdin
 

The CLI SAPI has three different ways of getting the PHP code you want to execute:

  1. Telling PHP to execute a certain file.
    php my_script.php
    
    php -f my_script.php
    Both ways (whether using the -f switch or not) execute the file my_script.php. You can choose any file to execute - your PHP scripts do not have to end with the .php extension but can have any name or extension you wish.  
     

  2. Pass the PHP code to execute directly on the command line.
     
    php -r 'print_r(get_defined_constants());'
    Special care has to be taken in regards of shell variable substitution and quoting usage.  

    Note: Read the example carefully, there are no beginning or ending tags! The -r switch simply does not need them. Using them will lead to a parser error.

  3. Provide the PHP code to execute via standard input (stdin).

    This gives the powerful ability to dynamically create PHP code and feed it to the binary, as shown in this (fictional) example:

    $ some_application | some_filter | php | sort -u >final_output.txt
     

You cannot combine any of the three ways to execute code.

Like every shell application, the PHP binary accepts a number of arguments but your PHP script can also receive arguments. The number of arguments which can be passed to your script is not limited by PHP (the shell has a certain size limit in the number of characters which can be passed; usually you won't hit this limit). The arguments passed to your script are available in the global array $argv. The zero index always contains the script name (which is - in case the PHP code is coming from either standard input or from the command line switch -r). The second registered global variable is $argc which contains the number of elements in the $argv array (not the number of arguments passed to the script).

As long as the arguments you want to pass to your script do not start with the - character, there's nothing special to watch out for. Passing an argument to your script which starts with a - will cause trouble because PHP itself thinks it has to handle it. To prevent this, use the argument list separator --. After this separator has been parsed by PHP, every argument following it is passed untouched to your script.

# This will not execute the given code but will show the PHP usage
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# This will pass the '-h' argument to your script and prevent PHP from showing it's usage
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}
 

However, there's another way of using PHP for shell scripting. You can write a script where the first line starts with #!/usr/bin/php. Following this you can place normal PHP code included within the PHP starting and end tags. Once you have set the execution attributes of the file appropriately (e.g. chmod +x test) your script can be executed like a normal shell or perl script:

#!/usr/bin/php
<?php
var_dump
($argv);
?>
Assuming this file is named test in the current directory, we can now do the following:
$ chmod +x test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}
As you see, in this case no care needs to be taken when passing parameters which start with - to your script.  

Long options are available since PHP 4.3.3.

Option Long Option Description
-a --interactive Runs PHP interactively. If you compile PHP with the Readline extension (which is not available on windows), you'll have a nice shell, including a completion feature (e.g. you can start typing a variable name, hit the TAB key and PHP completes its name) and a typing history that can be accessed using the arrow keys. The history is saved in the ~/.php_history file.

Note: Files included through auto_prepend_file and auto_append_file are parsed in this mode but with some restrictions - e.g. functions have to be defined before called.

-c --php-ini With this option one can either specify a directory where to look for php.ini or you can specify a custom INI file directly (which does not need to be named php.ini), e.g.:
$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php
If you don't specify this option, file is searched in default locations.  

-n --no-php-ini Ignore php.ini at all. This switch is available since PHP 4.3.0.
-d --define This option allows you to set a custom value for any of the configuration directives allowed in php.ini. The syntax is:
-d configuration_directive[=value]
 

Examples (lines are wrapped for layout reasons):

# Omitting the value part will set the given configuration directive to "1"
$ php -d max_execution_time
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Passing an empty value part will set the configuration directive to ""
php -d max_execution_time=
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# The configuration directive will be set to anything passed after the '=' character
$  php -d max_execution_time=20
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php
        -d max_execution_time=doesntmakesense
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"
 

-e --profile-info Activate the extended information mode, to be used by a debugger/profiler.
-f --file Parses and executed the given filename to the -f option. This switch is optional and can be left out. Only providing the filename to execute is sufficient.
-h and -? --help and --usage With this option, you can get information about the actual list of command line options and some one line descriptions about what they do.
-i --info This command line option calls phpinfo(), and prints out the results. If PHP is not working correctly, it is advisable to use php -i and see whether any error messages are printed out before or in place of the information tables. Beware that when using the CGI mode the output is in HTML and therefore quite huge.
-l --syntax-check This option provides a convenient way to only perform a syntax check on the given PHP code. On success, the text No syntax errors detected in <filename> is written to standard output and the shell return code is 0. On failure, the text Errors parsing <filename> in addition to the internal parser error message is written to standard output and the shell return code is set to 255.

This option won't find fatal errors (like undefined functions). Use -f if you would like to test for fatal errors too.

Note: This option does not work together with the -r option.

-m --modules Using this option, PHP prints out the built in (and loaded) PHP and Zend modules:
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]
 

-r --run This option allows execution of PHP right from within the command line. The PHP start and end tags (<?php and ?>) are not needed and will cause a parser error if present.

Note: Care has to be taken when using this form of PHP to not collide with command line variable substitution done by the shell.

Example showing a parser error

$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '='
The problem here is that the sh/bash performs variable substitution even when using double quotes ". Since the variable $foo is unlikely to be defined, it expands to nothing which results in the code passed to PHP for execution actually reading:
$ php -r " = get_defined_constants();"
The correct way would be to use single quotes '. Variables in single-quoted strings are not expanded by sh/bash.
$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]
If you are using a shell different from sh/bash, you might experience further issues. Feel free to open a bug report at http://bugs.php.net/. One can still easily run into troubles when trying to get shell variables into the code or using backslashes for escaping. You've been warned.  

Note: -r is available in the CLI SAPI and not in the CGI SAPI.

Note: This option is meant for a very basic stuff. Thus some configuration directives (e.g. auto_prepend_file and auto_append_file) are ignored in this mode.

-B --process-begin PHP code to execute before processing stdin. Added in PHP 5.
-R --process-code PHP code to execute for every input line. Added in PHP 5.

There are two special variables available in this mode: $argn and $argi. $argn will contain the line PHP is processing at that moment, while $argi will contain the line number.

-F --process-file PHP file to execute for every input line. Added in PHP 5.
-E --process-end PHP code to execute after processing the input. Added in PHP 5.

Example of using -B, -R and -E options to count the number of lines of a project.

$ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";'
Total Lines: 37328
 

-s --syntax-highlight and --syntax-highlight Display colour syntax highlighted source.

This option uses the internal mechanism to parse the file and produces a HTML highlighted version of it and writes it to standard output. Note that all it does it to generate a block of <code> [...] </code> HTML tags, no HTML headers.

Note: This option does not work together with the -r option.

-v --version Writes the PHP, PHP SAPI, and Zend version to standard output, e.g.
$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies
 

-w --strip Display source with stripped comments and whitespace.

Note: This option does not work together with the -r option.

-z --zend-extension Load Zend extension. If only a filename is given, PHP tries to load this extension from the current default library path on your system (usually specified /etc/ld.so.conf on Linux systems). Passing a filename with an absolute path information will not use the systems library search path. A relative filename with a directory information will tell PHP only to try to load the extension relative to the current directory.

 

The PHP executable can be used to run PHP scripts absolutely independent from the web server. If you are on a Unix system, you should add a special first line to your PHP script, and make it executable, so the system will know, what program should run the script. On a Windows platform you can associate php.exe with the double click option of the .php files, or you can make a batch file to run the script through PHP. The first line added to the script to work on Unix won't hurt on Windows, so you can write cross platform programs this way. A simple example of writing a command line PHP program can be found below.

Example 43-1. Script intended to be run from command line (script.php)
#!/usr/bin/php
<?php

if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

<?php
} else {
   echo
$argv[1];
}
?>
 

In the script above, we used the special first line to indicate that this file should be run by PHP. We work with a CLI version here, so there will be no HTTP header printouts. There are two variables you can use while writing command line applications with PHP: $argc and $argv. The first is the number of arguments plus one (the name of the script running). The second is an array containing the arguments, starting with the script name as number zero ($argv[0]).

In the program above we checked if there are less or more than one arguments. Also if the argument was --help, -help, -h or -?, we printed out the help message, printing the script name dynamically. If we received some other argument we echoed that out.

If you would like to run the above script on Unix, you need to make it executable, and simply call it as script.php echothis or script.php -h. On Windows, you can make a batch file for this task:

Example 43-2. Batch file to run a command line PHP script (script.bat)
@C:\php\php.exe script.php %1 %2 %3 %4
 

Assuming you named the above program script.php, and you have your CLI php.exe in C:\php\php.exe this batch file will run it for you with your added options: script.bat echothis or script.bat -h.

See also the Readline extension documentation for more functions you can use to enhance your command line applications in PHP.

Notes:
  • Those pages are written by people for whom English is not a native language. Some amount of grammar and spelling errors should be expected.
  • This is a Spartan WHYFF (We Help You For Free) site. It cannot replace the best teachers and the best books.
  • The site contain some obsolete pages as it develops like a living tree... Some links on older pages are broken. Please try to use Google, Open directory, etc. to find a replacement link (see HOWTO search the WEB for details). We would appreciate if you can mail us a correct link.

Search Amazon by keywords:

Google   
Open directory

Research Index

 
 

News

[Jul 10, 2006] International PHP Magazine Featured ArticlePHP CLI Unveiled!

In the weird and wonderful world of scripting languages, no languages demand more respect than those listed under the letter P in the scripter’s dictionary. For years system administrators have relied on these distinguished scripting languages to do everything from trivial computer maintenance tasks to providing backends to mission critical systems. Perl and Python have served us well, but while their pundits do battle for supremacy in the command line arena, PHP has been gathering its forces.

Quietly and with little ado, PHP 5 has brought the power and strengths of PHP to the command line, making PHP a tool of choice for Web developers and system administrators alike.

[Nov 27, 2002] Some Thoughts on PHP

Author:   John Lim    
Posted: 11/27/2002; 9:37:30 AM
Topic: Some Thoughts on PHP
Msg #: 2082 (top msg in thread)
Prev/Next: 2078/2085
Reads: 8413

Some Thoughts on PHP I just received this interesting email from Derek Comartin. I thought I would share his message and my response with you.

John,

I have been reading PHPEverywhere ever since I found it about a year back. I love reading it and your thoughts about the latest tech. Just recently I started using ADOdb for a project and love it. I am not a huge fan of PEAR's DB or PEAR in general (although I am using its SOAP package).

Anyways, the real point of my e-mail is that I am really getting frustrated with PHP. I have been developing applications with PHP for 3 years now, mainly developing intranet and CMS the like. My problem is that it seems like PHP is close to what I want it todo, but not quite. I would like to hear your thoughts and the thoughts of other php developers (people that use it everyday).

Let me say first of all I have absolutely no influence on the direction of PHP. I do not have CVS access to the PHP source code, and wouldn't have the time to contribute even if I wanted to. However some people might be interested in my opinion.

To me PHP is a pragmatic language. It is not based on any formal theory nor specification. It grew the same way as Perl, due to demand from skilled hackers. However Rasmus Lerdorf and company seem to be more keen on pruning the core language than the Perl gods and keeping it really simple. For example, to me the lack of the more advanced OOP features is a blessing. I was never impressed with C++ and its complexity, although I coded in it nearly every working day for 5 years.

(BTW, sorry if this is going to get long.. my real goal here is maybe you can post this on your site and hope to get some feedback in your comments section).

1) Templates Almost everyone agrees that mixing HTML and PHP is a bad idea. Personally I have developed my own template library that is simple and thin. Since PHP is geared toward web applications why in gods name don't they develop a SIMPLE template library built-into PHP. I cannot understand for 1 minute the point of smarty? I do think smarty is a very well designed library but I don't understand the point of making a library that introduces more business logic. Isn't the point of a template to seperate buisiness logic from UI? Who is coming up with this stuff?

The development of templates was an attempt to fight against complexity. This is good. Yes PHP is a template-based language, but that doesn't mean that good techniques preclude more advanced strategies for separating code,data and presentation. For very big scripts, we split code into functions and into several include files. We store data in an RDBMS for better management. So for very big web pages, it makes sense to split it into multiple files, and split presentation to template files too. Then we have a N-layer architecture of:

DATABASE 
   |
PHP BUSINESS LOGIC
   |
PRESENTATION LAYER TEMPLATES
   | 
PHP ENGINE 
   |
APACHE

From a theoretical point of view, perhaps Smarty has gone too far. Smarty does not merely deal with presentation issues, but has a full-blown programming language built-in. There is always the temptation to add functionality to something that began as a simple project. In some ways, Smarty compiled code is obfusticated PHP :-)

However from a commercial perspective, Smarty is cool. I can release a Zend encoded PHP product, and provide customization features by basing my user interface on Smarty, which the client can modify and even script without touching my compiled code.

So it really depends on your perspective. One man's Toyota is another man's Rolls Royce. And some people refuse to learn to drive and will never see the point of using Smarty.

(BTW: I have been wondering if someone has written a template library that is something like this:

If you had a template that had a <form id="myForm"> tag, then in your PHP you could modify tag properties etc... im not sure if ASP.net does something like this.. so your code would be:

$tmpl->myForm->setAction('myform.cgi');
$tmpl->myForm->setMethod('POST');

Kinda like how Javascript can minipulate objects, you could do with any HTML tag.. ie: forms, tables, yadda yadda

There are several libraries that do this already if you search on hotscripts.com. including (wink-wink) my company's product, phpLens which goes one step further in providing graphical ui designers/wizards. And my point of view is a little bit more radical - doing this without graphical aids is a step backward. For example this doesn't excite me:

$tmpl->myForm->DrawInput('text',$size=32,$maxlength=64);

because you lose the benefits of a graphical tool like dreamweaver that recognizes input tags for the obscure benefit of coding everything as objects. Half the power of MS.NET is the graphical tools of Visual Studio.NET.

Note that I had to use $size and $maxlength before you could even guess what the parameters of the function were. The beauty of HTML is that it is self-documenting.

2) Database

Thanks to you I use a great database abstraction. But why on earth isnt there abstraction built-in? I still like having functions for a specific API, but there should be db abstraction on top of that built in for speed.

Anyways these are just my random thoughts... I love PHP but there are too many things that are beginning to piss me off (did I also mention nonsense like how functions like explode, strstr have there haystack/needle arguments in different orders? Shouldnt this be common across all functions.... ah the little things.)

What are your thoughts?

PHP was developed to meet a need. PHP has grown organically, not because it was sponsored by big companies like Sun or IBM (eg java). People originally used PHP to create web-sites where the database was probably known; in contrast, database abstraction is only required if you are creating web applications that can be installed in different environments. I rarely do web-sites, most of my PHP work is for web-applications that run on Intranets/Extranets. That's how ADOdb came about. That's how PHP came about - to meet an immediate need.

So as PHP has matured, so has the needs become more sophisticated. Some people will always want PHP to do more and grow in more powerful ways (data abstraction, 100% OOP, etc), but as PHP growth is organic, you have to wait till someone faces the problem and comes up with the solution and post it to the net. This laissez-faire approach works because the number of PHP developers has reached a critical mass (perhaps when PHP4 was released).

Of course some things could have been better planned from the beginning of PHP, but no one would have started work till the last bit of the plan was nailed solid, which would have taken too long. Instead Zeev and Andi (and Rasmus?) are still very conservative about the core language, and they let you and me build whatever we like without comment. PHP-Nuke and Post-Nuke might never have been developed if Rasmus had blessed Midgard as the way to go. Of course there are people who say that the Nuke forks cannot compare to Zope or Soup or Whatever, or that the PHP api is not as nice as Java's or Python's -- but that misses the point. Millions of people are using and benefiting from the free software when programming in Java or Python or C# would have been too difficult. And this gives impetus for people to create better software.

-- John Lim PHPBuilder.com - Introduction to PHP5

PHP5 is not yet official but the development versions are already usable (and unstable!) so we can start to learn and practice the new features of the upcoming version of PHP. In this article I will focus in three major new features of PHP5:.

* The new object model
* Exceptions
* Namespaces

First of all a couple of disclaimers:

* Some of the techniques described in this article can be done with PHP4, but are presented anyway to make the whole article more readable.
* Some of the features described in this article may change in the final release of PHP5.

PHP5 has not been released yet and I don't know when that will be but you can already try and investigate the new features of the language by downloading and installing a PHP5 development version from http://snaps.php.net. There you will find Linux and Windows versions of PHP5 ready to be used. Installation proceeds as in any normal PHP distribution so go there and grab a brand new toy.

 

Message # 1016053:
Date: 04/12/03 07:01
By: Marcel Swinkels
Subject: Oh my god!

If this is the future for PHP why not start using JSP? :-(

 

Message # 1016064:
Date: 04/13/03 11:28
By: John C. Ghormley Profile
Subject: Look like Java to me

As an old time procedural coder, I didn't continue to pursue Java simply because I can't seem to get my mind around the OO paradigm when trying to think through a problem. So PHP was a great solution. Very procedural even if not politically correct for the times. Now, it seems the powers of PHP want to make it OO. That causes me a bit of concern and the concerns are these:
1) We're adding a lot of code overhead into the PHP code base to support OO.
2) Will that additional overhead slow the response time of PHP significantly?
3) If it does, how soon will the procedural elements begin to be extracted in favor of a more politically acceptable OO?
4) Assuming there is not degradation in performance, how soon will the pressure to conform to more politically acceptable practices cause the procedural elements to disappear?

On first read, I think i'd concur with Swinkels -- why not switch to JSP?
Message # 1016192:
Date: 04/20/03 17:24
By: Scott R.S.
Subject: RE: Look like Java to me

PHP CURRENTLY (4.3.x) outruns any JAVA code and 99% of the latest .NET stuff from Microsoft/MajorGreedy!!! Mind you I spent YEARS as a die hard MS guru building major systems for investment and retail banks as well as insurance, medical and communications sectors using MS tools. I looked at moving to Java and being something of a purist found all the OOP crap (forgive me folks) to be much ado about nothing that simply adds significant amounts of time and thus expense to projects without being able to support the speed and stability enterprise customers demand. Further while Java is somewhat portable, it still has light years to go before it can compete with .NET in terms of speed... I kept looking, and then, the BEST OF BREED, PHP!!!! Portable, powerful, FAST when it's free and when you compile it, get out of the way!!!!!!!! What a piece of software!!!! Take a look at http://www.partysite.com for some compiled PHP in action, be sure to notice the transaction timer in the lower left corner of results, then keep in mind the database has 1.7 million rows in it right now. Let's see MS or Java do that in under a second, oh that's right, THEY CAN'T!!!! The math ALONE is too much for either to support at any speed, then factor in the amount of data involved and neither can hope to touch it... I know, I was CTO of a startup that TRIED to build something for insurance companies in WINDOWS and WITHOUT any math, and only a couple hundred thousand records CHOKED and locked up the server... Want REAL power, and speed (which is simply defined as "power in excess of a given task") then build in PHP and compile it!!!! Compiling PHP is now SO MUCH more affordable with the Small business program from http://ZEND.COM that it pays to compile!!!!

Scott....
Message # 1016118:
Date: 04/15/03 08:39
By: Zeev Suraski
Subject: PHP's direction - reassurance

Just to reassure the people here that don't want to see PHP becoming an OO language - have no worries, this is not going to happen.

We've definitely added lots of OO features to the Zend Engine 2, but all of the structured code features remain intact. PHP's built-in functions are and will remain procedural. I think Jean-Marc hit it well - we want to give authors of larger-scale projects, or those that buy into the OO model, the tools to write their apps better. They've been using OO in PHP 4, but were bumping into all sorts of problems and limitations. We have no plan or will to try and encourage people to move away from procedural programming if they're happy with it.
Message # 1016603:
Date: 05/29/03 01:36
By: Excorcist
Subject: This is so stupid

I can't believe this

In PHP4 as you may already know variables are passed to functions/methods by value (a copy is passed) unless you use the '&' symbol in the function declaration indicating that the variable will be passed as a reference. In PHP5 objects will be passed always as references. Object assignation is also done by reference.

WTF is that crap??? You're trying to rip php out of it's roots and make it some kind of psuedo java. WHat the hell? If this isn't a step backwards I don't know what is. My god I can't believe this.
Message # 1016746:
Date: 06/16/03 04:34
By: Zeev Suraski
Subject: RE: This is so stupid

You should be thankful, then, that you'd be able to enable compatibility mode and have your objects behave in the same way as previous versions of PHP have, and be passed by value.

If you consider the old behavior an advantage, in any way, then I believe you've never written an OO piece of code. That's fine, by the way - as PHP 5 will definitely not force you to write OO, it'll just make it a heck of a lot easier.
Message # 1016750:
Date: 06/16/03 10:16
By: David Fells
Subject: I guess IL is next...

Seems like the php team is on the right track with finally giving try/catch exception handling and providing access modifier keywords for class members. I'm just not really convinced of the necessity in using OOP in php...

In some tests I ran recently before deciding whether to completely rebuild or just reuse some old code someone else wrote for a new project, the OOP code they wrote ran approximately 10 times more slowly than the procedural code I wrote... by simply putting what would be a "class" in it's own include file and including as needed, you still have the basic reusability of OOP without the extra compile/execute time of objects.

I'm just afraid the addition of namespaces, exception catching, catchalls, and access modifiers are only going to make the performance of OOP in PHP get worse =( I just hope they don't choose to go to an IL/JIT model to compensate ! Yuck.
Message # 1016549:
Date: 05/21/03 19:27
By: Brandon Goodin
Subject: RE: Look like Java to me

Let me preface by saying.. 'to each their own'.

Having been a long time Java programmer and currently still, I find that many of the comments that have been made in this thread regarding java are outdated and even innacurate.

I don't have the time to go back and speak on each point specifically. But, from a personal standpoint Java has been progessing as fast and furious as other technologies (including php). Short comings from 2 years ago don't apply to today.

To state some positives about Java:
- Object generation and garbage collection has improved drastically.
- Various open-source and commercial frameworks have emerged to allow for quick and efficient assembly of applications (client and server). Most use good OO design patterns.
- Because of the decoupling of various layers of the application better code management is possible. (i.e View/Controller/Logic/Data Layer/Web Services)

I encourage you all to post your statements to a Java discussion board and see what responses you get. You might learn something about Java that you didn't know.

Personally, I like php. It's a great language... for the web and for small-midsize to small jobs. I got away from the page scripting as a mainstay because it became to difficult to manage in a team environment. All of the dependencies on the view passing the right parameters to the next page and the tight coupling with the data layer in the end makes things too complex. I use good php coding standards. But, it still doesn't compete with a well formed Java envrionment. Once the job gets to a certain size I find that I can create in Java a lot faster.

I think the direction that php is going with it's Java/C# OOP look and feel is a good thing. But, even with php5 it appears it has a ways to go before it's competing with the maturity of Java/C#/Python type OOP languages. BTW for all the complaining against OOP I find it humorous that php is adopting the very principals you dislike. Procedural will always be around. But in the economy of scale (IMHO) OOP wins.

So, long live PHP OOP!!! :-))

Recommended Links

PHP: Using PHP from the command line - Manual

PHP CLI and Cron

RPM resource php-cli

Etc

add a note add a note User Contributed Notes
Using PHP from the command line
16-Sep-2006 12:05
It seems like 'max_execution_time' doesn't work on CLI.

<?php
php
-d max_execution_time=20
      
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
?>
will print string(2) "20", but if you'l run infinity while: while(true) for example, it wouldn't stop after 20 seconds.
Testes on Linux Gentoo, PHP 5.1.6.
hobby6_at_hotmail.com
15-Sep-2006 04:59
On windows, you can simulate a cls by echoing out just \r.  This will keep the cursor on the same line and overwrite what was on the line.

for example:

<?php
  
echo "Starting Iteration" . "\n\r";
   for (
$i=0;$i<10000;$i++) {
       echo
"\r" . $i;
   }
   echo
"Ending Iteration" . "\n\r";
?>
goalain eat gmail dont com
21-Aug-2006 01:20
If your php script doesn't run with shebang (#!/usr/bin/php),
and it issues the beautifull and informative error message:
"Command not found."  just dos2unix yourscript.php
et voila.

If your php script doesn't run with shebang (#/usr/bin/php),
and it issues the beautifull and informative message:
"Invalid null command." it's probably because the "!" is missing in the the shebang line (like what's above) or something else in that area.

\Alon
stromdotcom at hotmail dot com
21-Feb-2006 11:27
Spawning php-win.exe as a child process to handle scripting in Windows applications has a few quirks (all having to do with pipes between Windows apps and console apps).

To do this in C++:

// We will run php.exe as a child process after creating
// two pipes and attaching them to stdin and stdout
// of the child process
// Define sa struct such that child inherits our handles

SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES) };
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;

// Create the handles for our two pipes (two handles per pipe, one for each end)
// We will have one pipe for stdin, and one for stdout, each with a READ and WRITE end
HANDLE hStdoutRd, hStdoutWr, hStdinRd, hStdinWr;

// Now create the pipes, and make them inheritable
CreatePipe (&hStdoutRd, &hStdoutWr, &sa, 0))
SetHandleInformation(hStdoutRd, HANDLE_FLAG_INHERIT, 0);
CreatePipe (&hStdinRd, &hStdinWr, &sa, 0)
SetHandleInformation(hStdinWr, HANDLE_FLAG_INHERIT, 0);

// Now we have two pipes, we can create the process
// First, fill out the usage structs
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hStdoutWr;
si.hStdInput  = hStdinRd;

// And finally, create the process
CreateProcess (NULL, "c:\\php\\php-win.exe", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);

// Close the handles we aren't using
CloseHandle(hStdoutWr);
CloseHandle(hStdinRd);

// Now that we have the process running, we can start pushing PHP at it
WriteFile(hStdinWr, "<?php echo 'test'; ?>", 9, &dwWritten, NULL);

// When we're done writing to stdin, we close that pipe
CloseHandle(hStdinWr);

// Reading from stdout is only slightly more complicated
int i;

std::string processed("");
char buf[128];

while ( (ReadFile(hStdoutRd, buf, 128, &dwRead, NULL) && (dwRead != 0)) ) {
   for (i = 0; i < dwRead; i++)
       processed += buf[i];
}   

// Done reading, so close this handle too
CloseHandle(hStdoutRd);

A full implementation (implemented as a C++ class) is available at http://www.stromcode.com
drewish at katherinehouse dot com
25-Sep-2005 01:08
When you're writing one line php scripts remember that 'php://stdin' is your friend. Here's a simple program I use to format PHP code for inclusion on my blog:

UNIX:
  cat test.php | php -r "print htmlentities(file_get_contents('php://stdin'));"

DOS/Windows:
  type test.php | php -r "print htmlentities(file_get_contents('php://stdin'));"
OverFlow636 at gmail dot com
19-Sep-2005 01:27
I needed this, you proly wont tho.
puts the exicution args into $_GET
<?php
if ($argv)
   for (
$i=1;$i<count($argv);$i++)
   {
      
$it = split("=",$argv[$i]);
      
$_GET[$it[0]] = $it[1];
   }
?>
php at schabdach dot de
16-Sep-2005 10:06
To pass more than 9 arguments to your php-script on Windows, you can use the 'shift'-command in a batch file. After using 'shift', %1 becomes %0, %2 becomes %1 and so on - so you can fetch argument 10 etc.

Here's an example - hopefully ready-to-use - batch file:

foo.bat:
---------
@echo off

:init_arg
set args=

:get_arg
shift
if "%0"=="" goto :finish_arg
set args=%args% %0
goto :get_arg
:finish_arg

set php=C:\path\to\php.exe
set ini=C:\path\to\php.ini
%php% -c %ini% foo.php %args%
---------

Usage on commandline:
foo -1 -2 -3 -4 -5 -6 -7 -8 -9 -foo -bar

A print_r($argv) will give you all of the passed arguments.
Lasse Johansson
18-Aug-2005 02:53
Hi, parsing the commandline (argv) can be very simple in PHP.
If you use keyword parms like:

script.php parm1=value parm3=value

All you have to do in script.php is:

for ($i=1; $i < $argc; $i++) {parse_str($argv[$i]);}
$startup=compact('parm1', 'parm2', 'parm3');
docey
14-Jul-2005 06:44
dunno if this is on linux the same but on windows evertime
you send somthing to the console screen php is waiting for
the console to return. therefor if you send a lot of small
short amounts of text, the console is starting to be using
more cpu-cycles then php and thus slowing the script.

take a look at this sheme:
cpu-cycle:1 ->php: print("a");
cpu-cycle:2 ->cmd: output("a");
cpu-cycle:3 ->php: print("b");
cpu-cycle:4 ->cmd: output("b");
cpu-cycle:5 ->php: print("c");
cpu-cycle:6 ->cmd: output("c");
cpu-cylce:7 ->php: print("d");
cpu-cycle:8 ->cmd: output("d");
cpu-cylce:9 ->php: print("e");
cpu-cycle:0 ->cmd: output("e");

on the screen just appears "abcde". but if you write
your script this way it will be far more faster:
cpu-cycle:1 ->php: ob_start();
cpu-cycle:2 ->php: print("abc");
cpu-cycle:3 ->php: print("de");
cpu-cycle:4 ->php: $data = ob_get_contents();
cpu-cycle:5 ->php: ob_end_clean();
cpu-cycle:6 ->php: print($data);
cpu-cycle:7 ->cmd: output("abcde");

now this is just a small example but if you are writing an
app that is outputting a lot to the console, i.e. a text
based screen with frequent updates, then its much better
to first cach all output, and output is as one big chunk of
text instead of one char a the time.

ouput buffering is ideal for this. in my script i outputted
almost 4000chars of info and just by caching it first, it
speeded up by almost 400% and dropped cpu-usage.

because what is being displayed doesn't matter, be it 2
chars or 40.0000 chars, just the call to output takes a
great deal of time. remeber that.

maybe someone can test if this is the same on unix-based
systems. it seems that the STDOUT stream just waits for
the console to report ready, before continueing execution.
wallacebw
24-Jun-2005 09:07
For windows clearing the screen using "system('cls');" does not work (at least for me)...

Although this is not pretty it works... Simply send 24 newlines after the output (for one line of output, 23 for two, etc

Here is a sample function and usage:

   function CLS($lines){  // $lines = number of lines of output to keep
       for($i=24;$i>=$lines;$i--) @$return.="\n";
       return $return;
   }
 
   fwrite(STDOUT,"Still Processing: Total Time ".$i." Minutes so far..." . CLS(1));

Hope This Helps,
Wallacebw
linus at flowingcreativity dot net
30-May-2005 08:32
If you are using Windows XP (I think this works on 2000, too) and you want to be able to right-click a .php file and run it from the command line, follow these steps:

1. Run regedit.exe and *back up the registry.*
2. Open HKEY_CLASSES_ROOT and find the ".php" key.

IF IT EXISTS:
------------------
3. Look at the "(Default)" value inside it and find the key in HKEY_CLASSES_ROOT with that name.
4. Open the "shell" key inside that key. Skip to 8.

IF IT DOESN'T:
------------------
5. Add a ".php" key and set the "(Default)" value inside it to something like "phpscriptfile".
6. Create another key in HKEY_CLASSES_ROOT called "phpscriptfile" or whatever you chose.
7. Create a key inside that one called "shell".

8. Create a key inside that one called "run".
9. Set the "(Default)" value inside "run" to whatever you want the menu option to be (e.g. "Run").
10. Create a key inside "run" called "command".
11. Set the "(Default)" value inside "command" to:

cmd.exe /k C:\php\php.exe "%1"

Make sure the path to PHP is appropriate for your installation. Why not just run it with php.exe directly? Because you (presumably) want the console window to remain open after the script ends.

You don't need to set up a webserver for this to work. I downloaded PHP just so I could run scripts on my computer. Hope this is useful!
roberto dot dimas at gmail dot com
26-May-2005 02:52
One of the things I like about perl and vbscripts, is the fact that I can name a file e.g. 'test.pl' and just have to type 'test, without the .pl extension' on the windows command line and the command processor knows that it is a perl file and executes it using the perl command interpreter.

I did the same with the file extension .php3 (I will use php3 exclusivelly for command line php scripts, I'm doing this because my text editor VIM 6.3 already has the correct syntax highlighting for .php3 files ).

I modified the PATHEXT environment variable in Windows XP, from the " 'system' control panel applet->'Advanced' tab->'Environment Variables' button-> 'System variables' text area".

Then from control panel "Folder Options" applet-> 'File Types' tab, I added a new file extention (php3), using the button 'New'  and typing php3 in the window that pops up.

Then in the 'Details for php3 extention' area I used the 'Change' button to look for the Php.exe executable so that the php3 file extentions are associated with the php executable.

You have to modify also the 'PATH' environment variable, pointing to the folder where the php executable is installed

Hope this is useful to somebody
diego dot rodrigues at poli dot usp dot br
02-May-2005 09:29
#!/usr/bin/php -q
<?
/**********************************************
* Simple argv[] parser for CLI scripts
* Diego Mendes Rodrigues - S㯠Paulo - Brazil
* diego.m.rodrigues [at] gmail [dot] com
* May/2005
**********************************************/

class arg_parser {
   var
$argc;
   var
$argv;
   var
$parsed;
   var
$force_this;

   function
arg_parser($force_this="") {
       global
$argc, $argv;
      
$this->argc = $argc;
      
$this->argv = $argv;
      
$this->parsed = array();
      
      
array_push($this->parsed,
                           array(
$this->argv[0]) );

       if ( !empty(
$force_this) )
           if (
is_array($force_this) )
              
$this->force_this = $force_this;

      
//Sending parameters to $parsed
      
if ( $this->argc > 1 ) {
           for(
$i=1 ; $i< $this->argc ; $i++) {
              
//We only have passed -xxxx
              
if ( substr($this->argv[$i],0,1) == "-" ) {
                  
//Se temos -xxxx xxxx
                  
if ( $this->argc > ($i+1) ) {
                       if (
substr($this->argv[$i+1],0,1) != "-" ) {
                          
array_push($this->parsed,
                               array(
$this->argv[$i],
                                  
$this->argv[$i+1]) );
                          
$i++;
                           continue;
                       }
                   }
               }
              
//We have passed -xxxxx1 xxxxx2
              
array_push($this->parsed,
                                                 array(
$this->argv[$i]) );
           }
       }

              
//Testing if all necessary parameters have been passed
              
$this->force();
   }

  
//Testing if one parameter have benn passed
  
function passed($argumento) {
       for(
$i=0 ; $i< $this->argc ; $i++)
           if (
$this->parsed[$i][0] == $argumento )
               return
$i;
       return
0;
   }

  
//Testing if you have passed a estra argument, -xxxx1 xxxxx2
  
function full_passed($argumento) {
      
$findArg = $this->passed($argumento);
       if (
$findArg )
           if (
count($this->parsed[$findArg] ) > 1 )
               return
$findArg;
       return
0;
   }

      
//Returns  xxxxx2 at a " -xxxx1 xxxxx2" call
  
function get_full_passed($argumento) {
              
$findArg = $this->full_passed($argumento);

               if (
$findArg )
                   return
$this->parsed[$findArg][1];

               return;
       }
  
  
//Necessary parameters to script
  
function force() {
       if (
is_array( $this->force_this ) ) {
           for(
$i=0 ; $i< count($this->force_this) ; $i++) {
               if (
$this->force_this[$i][1] == "SIMPLE"
                    
&& !$this->passed($this->force_this[$i][0])
               )
                   die(
"\n\nMissing " . $this->force_this[$i][0] . "\n\n");

                               if (
$this->force_this[$i][1] == "FULL"
                                    
&& !$this->full_passed($this->force_this[$i][0])
               )
                                       die(
"\n\nMissing " . $this->force_this[$i][0] ." <arg>\n\n");
           }
       }
   }
}

//Example
$forcar = array(
       array(
"-name", "FULL"),
       array(
"-email","SIMPLE") );

$parser = new arg_parser($forcar);

if (
$parser->passed("-show") )
   echo
"\nGoing...:";

echo
"\nName: " . $parser->get_full_passed("-name");

if (
$parser->full_passed("-email") ) 
   echo
"\nEmail: " . $parser->get_full_passed("-email");
else
       echo
"\nEmail: default";

if (
$parser->full_passed("-copy") )
       echo
"\nCopy To: " . $parser->get_full_passed("-copy");

echo
"\n\n";
?>

TESTING
=====
[diego@Homer diego]$ ./en_arg_parser.php -name -email cool -copy Ana

Missing -name <arg>

[diego@Homer diego]$ ./en_arg_parser.php -name diego -email cool -copy Ana

Name: diego
Email: cool
Copy To: Ana

[diego@Homer diego]$ ./en_arg_parser.php -name diego -email  -copy Ana

Name: diego
Email: default
Copy To: Ana

[diego@Homer diego]$ ./en_arg_parser.php -name diego -email

Name: diego
Email: default

[diego@Homer diego]$
rh@hdesigndotdemondotcodotuk
25-Apr-2005 02:28
In a bid to save time out of lives when calling up php from the Command Line on Mac OS X.

I just wasted hours on this. Having written a routine which used the MCRYPT library, and tested it via a browser, I then set up a crontab to run the script from the command line every hour (to do automated backups from mysql using mysqldump, encrypt them using mcrypt, then email them and ftp them off to remote locations).

Everything worked fine from the browser, but failed every time from the cron task with "Call to undefined function: mcrypt [whatever]".

Only after much searching do I realise that the CGI and CLI versions are differently compiled, and have different modules attached (I'm using the entropy.ch install for Mac OS-X, php v4.3.2 and mysql v4.0.18).

I still can not find a way to resolve the problem, so I have decided instead to remove the script from the SSL side of the server, and run it using a crontab with CURL to localhost or 127.0.0.1 in order that it will run through Apache's php module.

Just thought this might help some other people tearing their hair out. If anyone knows a quick fix to add the mcrypt module onto the CLI php without any tricky re-installing, it'd be really helpful.

Meantime the workaround does the job, not as neatly though.
merrittd at dhcmc dot com
28-Mar-2005 02:23
Example 43-2 shows how to create a DOS batch file to run a PHP script form the command line using:

@c:\php\cli\php.exe script.php %1 %2 %3 %4

Here is an updated version of the DOS batch file:

@c:\php\cli\php.exe %~n0.php %*

This will run a PHP file (i.e. script.php) with the same base file name (i.e. script) as the DOS batch file (i.e. script.bat) and pass all parameters (not just the first four as in example 43-2) from the DOS batch file to the PHP file. 

This way all you have to do is copy/rename the DOS batch file to match the name of your PHP script file without ever having to actually modify the contents of the DOS batch file to match the file name of the PHP script.
13-Mar-2005 02:52
Here is very simple, but usefull Command Line handler class. it may be usefull for your apps.

http://www.pure-php.de/node/16
<?
require_once("CliHandler.class.php");

class
AnyClass{
  
public function start(){
       return
"started";
   }
  
public function stop(){
       return
"stoppded";
   }
}
$cli = new CliHandler(new AnyClass());
$cli->run();
?>

CliHandler accepts any class als argument.
Try this.

/usr/local/php/PHP5 CliHandler.class.php
output: Try these command:
start
stop
enter "start"
output: started
bertrand at toggg dot com
07-Mar-2005 09:40
If you want to pass directly PHP code to the interpreter and you don't have only CGI, not the CLI SAPI so you miss the -r option.
If you're lucky enough to be on a nix like system, then tou can still use the pipe solution as the 3. way to command CLI SAPI described above, using a pipe ('|').

Then works for CGI SAPI:

$ echo '<?php echo "coucou\n"; phpinfo(); /* or any code */ ?>' | php

NOTE: unlike commands passed to the -r option, here you NEED the PHP tags.
jeromenelson at gmail dot com
07-Mar-2005 02:21
This is the most simple way to get the named parameter.  Write the script test.php as ...

<?
  
echo "Yo! my name is ".$_REQUEST["name"]."\n";
?>

and run this program as follows

# php -f test.php name=Jerry
Yo! my name is Jerry

I am using PHP 4.3.3 (CGI) in Fedora Core 1 and It is working perfectly

God Bless You!
obfuscated at emailaddress dot com
25-Feb-2005 09:15
This posting is not a php-only problem, but hopefully will save someone a few hours of headaches.  Running on MacOS (although this could happen on any *nix I suppose), I was unable to get the script to execute without specifically envoking php from the command line:

[macg4:valencia/jobs] tim% test.php
./test.php: Command not found.

However, it worked just fine when php was envoked on the command line:

[macg4:valencia/jobs] tim% php test.php
Well, here we are...  Now what?

Was file access mode set for executable?  Yup.

[macg4:valencia/jobs] tim% ls -l
total 16
-rwxr-xr-x  1 tim  staff  242 Feb 24 17:23 test.php

And you did, of course, remember to add the php command as the first line of your script, yeah?  Of course.

#!/usr/bin/php
<?php print "Well, here we are...  Now what?\n"; ?>

So why dudn't it work?  Well, like I said... on a Mac.... but I also occasionally edit the files on my Windows portable (i.e. when I'm travelling and don't have my trusty Mac available)...  Using, say, WordPad on Windows... and BBEdit on the Mac...

Aaahhh... in BBEdit check how the file is being saved!  Mac?  Unix?  or Dos?  Bingo.  It had been saved as Dos format.  Change it to Unix:

[macg4:valencia/jobs] tim% ./test.php
Well, here we are...  Now what?
[macg4:valencia/jobs] tim%

NB: If you're editing your php files on multiple platforms (i.e. Windows and Linux), make sure you double check the files are saved in a Unix format...  those \r's and \n's 'll bite cha!
db at digitalmediacreation dot ch
22-Feb-2005 12:49
A very important point missing here (I lost hours on it and hope to avoid this to you) :

* When using PHP as CGI
* When you just become crazy because of "No input file specified" appearing on the web page, while it never appears directly in the shell

Then I have a solution for you :

1. Create a script for example called cgiwrapper.cgi
2. Put inside :
 #!/bin/sh -
 export SCRIPT_FILENAME=/var/www/realpage.php
 /usr/bin/php -f $SCRIPT_FILENAME
3. Name your page realpage.php

For example with thttpd the problem is that SCRIPT_FILENAME is not defined, while PHP absolutely requires it.
My solution corrects that problem !
Flo
11-Feb-2005 05:03
On windows try ctrl-m or ctrl-z to run code in interactive (-a) mode
(*nix ctrl-d)
ken.gregg at rwre dot com
09-Jan-2005 02:38
If you want to use named command line parameters in your script,
the following code will parse command line parameters in the form
of name=value and place them in the $_REQUEST super global array.

cli_test.php
<?php

echo "argv[] = ";
print_r($argv);  // just to see what was passed in

if ($argc > 0)
{
  for (
$i=1;$i < $argc;$i++)
  {
  
parse_str(