|
Softpanorama
(slightly skeptical)
Open Source Software Educational Society |
May the
source be with you,
but remember the KISS principle ;-)
|
Command Line PHP
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:
- Unlike the CGI SAPI, no headers
are written to the output.
- Though the CGI SAPI provides a way
to suppress HTTP headers, there's no equivalent switch to enable
them in the CLI SAPI.
- CLI is started up in quiet mode by default, though the
-q and --no-header
switches are kept for compatibility so that you can use older
CGI scripts.
- It does not change the working directory to that of the
script. (-C and
--no-chdir switches kept for compatibility)
- Plain text error messages (no HTML formatting).
- There are certain php.ini
directives which are overridden by the CLI
SAPI because they do not make sense in shell environments:
| Directive |
CLI SAPI default
value |
Comment |
|
html_errors |
FALSE |
It can be quite hard to read the error message
in your shell when it's cluttered with all those
meaningless HTML tags,
therefore this directive defaults to
FALSE.
|
|
implicit_flush |
TRUE |
It is desired that any output coming from
print(),
echo() and friends is
immediately written to the output and not cached in
any buffer. You still can use
output buffering if you want to defer or
manipulate standard output. |
|
max_execution_time |
0 (unlimited) |
Due to endless possibilities of using PHP in
shell environments, the maximum execution time has
been set to unlimited. Whereas applications written
for the web are often executed very quickly, shell
application tend to have a much longer execution
time. |
|
register_argc_argv |
TRUE |
Because this setting is
TRUE you will always have access to
argc
(number of arguments passed to the application) and
argv
(array of the actual arguments) in the
CLI SAPI.
As of PHP 4.3.0, the PHP variables
$argc and
$argv are registered and
filled in with the appropriate values when using the
CLI SAPI. Prior to this
version, the creation of these variables behaved as
they do in CGI and
MODULE versions which
requires the PHP directive
register_globals to be
on. Regardless of
version or register_globals setting, you can always
go through either
$_SERVER or
$HTTP_SERVER_VARS. Example:
$_SERVER['argv'] |
Note: These directives cannot be initialized
with another value from the configuration file
php.ini or a custom one (if
specified). This is a limitation because those default
values are applied after all configuration files have
been parsed. However, their value can be changed during
runtime (which does not make sense for all of those
directives, e.g.
register_argc_argv).
- To ease working in the shell environment, the following
constants are defined:
| Constant |
Description |
| STDIN |
An already opened stream to
stdin. This saves opening it with
|
<?php
$stdin =
fopen('php://stdin',
'r');
?>
|
If you want to read single line from
stdin, you can use
|
<?php
$line =
trim(fgets(STDIN));
fscanf(STDIN,
"%d\n",
$number);
?>
|
|
| STDOUT |
An already opened stream to
stdout. This saves opening it with
|
<?php
$stdout =
fopen('php://stdout',
'w');
?>
|
|
| STDERR |
An already opened stream to
stderr. This saves opening it with
|
<?php
$stderr =
fopen('php://stderr',
'w');
?>
|
|
Given the above, you don't need to open e.g. a stream for
stderr yourself but simply use the
constant instead of the stream resource:
php -r 'fwrite(STDERR, "stderr\n");'
|
You do not need to explicitly close these streams, as they are
closed automatically by PHP when your script ends.
- The CLI SAPI does
not change
the current directory to the directory of the executed script!
Example showing the difference to the
CGI SAPI:
|
<?php
echo
getcwd(),
"\n";
?>
|
When using the CGI version, the
output is:
$ pwd
/tmp
$ php -q another_directory/test.php
/tmp/another_directory
|
This clearly shows that PHP changes its current directory to the
one of the executed script.
Using the CLI SAPI yields:
$ pwd
/tmp
$ php -f another_directory/test.php
/tmp
|
This allows greater flexibility when writing shell tools in PHP.
Note: The CGI SAPI
supports this CLI SAPI
behaviour by means of the -C
switch when run from the command line.
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:
- 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.
- 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.
- 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.
|
| -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:
- This is a Spartan WHYFF (We Help
You For Free) site written by people for whom English
is not a native language.
Some amount of grammar and spelling errors should be
expected.
- The site contain some broken links
as it develops like a living tree...
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.
|
|
|
|
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.
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
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
<?
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;
if (
$this->argc
>
1 ) {
for($i=1
;
$i<
$this->argc
;
$i++)
{
if (
substr($this->argv[$i],0,1)
== "-"
) {
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;
}
}
}
array_push($this->parsed,
array($this->argv[$i])
);
}
}
$this->force();
}
function
passed($argumento)
{
for($i=0
;
$i<
$this->argc
;
$i++)
if ( $this->parsed[$i][0]
== $argumento
)
return $i;
return 0;
}
function
full_passed($argumento)
{
$findArg
=
$this->passed($argumento);
if ( $findArg
)
if ( count($this->parsed[$findArg]
) > 1
)
return
$findArg;
return 0;
}
function
get_full_passed($argumento)
{
$findArg
=
$this->full_passed($argumento);
if (
$findArg )
return
$this->parsed[$findArg][1];
return;
}
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");
}
}
}
}
$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();
?>' | 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);
if ($argc
>
0)
{
for ($i=1;$i
<
$argc;$i++)
{
parse_str($argv[$i],$tmp);
$_REQUEST
=
array_merge($_REQUEST,
$tmp);
}
}
echo "\$_REQUEST = ";
print_r($_REQUEST);
?>
rwre:~/tmp$ /usr/local/bin/php cli_test.php foo=1 bar=2
third=a+value
argv[] = Array
(
[0] => t.php
[1] => foo=1
[2] => bar=2
[3] => third=a+value
)
$_REQUEST = Array
(
[foo] => 1
[bar] => 2
[third] => a value
)
Ben Jenkins
21-Dec-2004 10:23
This took me all day to figure
out, so I hope posting it here saves someone some time:
Your PHP-CLI may have a different php.ini than your
apache-php. For example: On my Debian-based system, I
discovered I have /etc/php4/apache/php.ini and
/etc/php4/cli/php.ini
If you want MySQL support in the CLI, make sure the line
extension=mysql.so
is not commented out.
The differences in php.ini files may also be why some
scripts will work when called through a web browser, but
will not work when called via the command line.
linn at backendmedia dot com
06-Feb-2004 07:12
For those of you who want the
old CGI behaviour that changes to the actual directory
of the script use:
chdir(dirname($_SERVER['argv'][0]));
at the beginning of your scripts.
ben at slax0rnet dot com
02-Feb-2004 08:34
Just a note for people trying
to use interactive mode from the commandline.
The purpose of interactive mode is to parse code
snippits without actually leaving php, and it works like
this:
[root@localhost php-4.3.4]# php -a
Interactive mode enabled
<?php
echo
"hi!";
?>
<note, here we would press CTRL-D to parse
everything we've entered so far>
hi!
<?php
exit();
?>
<ctrl-d here again>
[root@localhost php-4.3.4]#
I noticed this somehow got ommited from the docs, hope
it helps someone!
phprsr at mindtwin dot com
05-Aug-2003 10:12
The basic issue was that
PHP-as-CGI REALLY REALLY wants SCRIPT_FILENAME.
It ignores the command line. It ignores SCRIPT_NAME. It
wants
SCRIPT_FILENAME.
"No input file specified."
This very informative error message from PHP means that
your web server, WHATEVER it is, is not setting
SCRIPT_FILENAME.
The minimum set of env variables:
PATH: DOESN'T MATTER if you're spawning php pages with
#!/../php in them
LD_LIBRARY_PATH= should be right
SERVER_SOFTWARE=mini_httpd/1.17beta1 26may2002
SERVER_NAME=who cares
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.0
SERVER_PORT=whatever
REQUEST_METHOD=GET
SCRIPT_NAME=/foo.php
SCRIPT_FILENAME=/homes/foobie/mini/foo.php <---
CRITICAL
QUERY_STRING==PHPE9568F35-D428-11d2-A769-00AA001ACF42
REMOTE_ADDR=172.17.12.80
HTTP_REFERER=http://booky16:10000/foo.php
HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.0; Q312461; .NET CLR 1.0.3705; .NET CLR
1.1.4322)
If SCRIPT_FILENAME is not set, you'll get the dreaded
"No input file specified" message.
mini_httpd does not do this by default. You need to
patch it in to make_envp.
A secondary issue is configuration (PHP):
./configure --enable-discard-path
--with-config-file-path=/homes/wherever/mini/php.ini
(where php.ini is a slightly modified version of
php.ini-recommended)
punk [_at_] studionew [_dot_] com
19-Jul-2003 05:18
You can use this function to
ask user to enter smth
<?
function
read
($length='255')
{
if (!isset ($GLOBALS['StdinPointer']))
{
$GLOBALS['StdinPointer']
= fopen
("php://stdin","r");
}
$line
=
fgets ($GLOBALS['StdinPointer'],$length);
return trim
($line);
}
echo
"Enter your name: ";
$name
=
read ();
echo "\nHello $name! Where
you came from? ";
$where
=
read ();
echo "\nI see. $where is
very good place.";
?>
Adam, php(at)getwebspace.com
17-Jun-2003 05:12
Ok, I've had a heck of a time
with PHP > 4.3.x and whether to use CLI vs CGI. The CGI
version of 4.3.2 would return (in browser):
---
No input file specified.
---
And the CLI version would return:
---
500 Internal Server Error
---
It appears that in CGI mode, PHP looks at the
environment variable PATH_TRANSLATED to determine the
script to execute and ignores command line. That is why
in the absensce of this environment variable, you get
"No input file specified." However, in CLI mode the HTTP
headers are not printed. I believe this is intended
behavior for both situations but creates a problem when
you have a CGI wrapper that sends environment variables
but passes the actual script name on the command line.
By modifying my CGI wrapper to create this
PATH_TRANSLATED environment variable, it solved my
problem, and I was able to run the CGI build of 4.3.2
monte at ispi dot net
04-Jun-2003 04:47
I had a problem with the $argv
values getting split up when they contained plus (+)
signs. Be sure to use the CLI version, not CGI to get
around it.
Monte
Popeye at P-t-B dot com
18-Apr-2003 09:15
In *nix systems, use the WHICH
command to show the location of the php binary
executable. This is the path to use as the first line in
your php shell script file. (#!/path/to/php -q) And
execute php from the command line with the -v switch to
see what version you are running.
example:
# which php
/usr/local/bin/php
# php -v
PHP 4.3.1 (cli) (built: Mar 27 2003 14:41:51)
Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend
Technologies
In the above example, you would use:
#!/usr/local/bin/php
Also note that, if you do not have the current/default
directory in your PATH (.), you will have to use
./scriptfilename to execute your script file from the
command line (or you will receive a "command not found"
error). Use the ENV command to show your PATH
environment variable value.
volkany at celiknet dot com
20-Feb-2003 02:44
Here goes a very simple clrscr
function for newbies...
function clrscr() { system("clear"); }
Alexander Plakidin
14-Feb-2003 06:34
How to change current directory
in PHP script to script's directory when running it from
command line using PHP 4.3.0?
(you'll probably need to add this to older scripts when
running them under PHP 4.3.0 for backwards
compatibility)
Here's what I am using:
chdir(preg_replace('/\\/[^\\/]+$/',"",$PHP_SELF));
Note: documentation says that "PHP_SELF" is not
available in command-line PHP scripts. Though, it IS
available. Probably this will be changed in future
version, so don't rely on this line of code...
Use $_SERVER['PHP_SELF'] instead of just $PHP_SELF if
you have register_globals=Off
c dot kelly[no--spam] at qfsaustrlia dot com dot au
06-Feb-2003 09:03
In Windows [NT4.0 sp6a] the
example
php -r ' echo getcwd();' does not work ; It appears you
have to use the following php -r "echo getcwd();" --not
the " around the command to get the output to screen ,
just took me half an hour to figure out what was going
on.
wanna at stay dot anonynous dot com
22-Jan-2003 10:42
TIP: If you want different
versions of the configuration file depending on what
SAPI is used,just name them php.ini (apache module),
php-cli.ini (CLI) and php-cgi.ini (CGI) and dump them
all in the regular configuration directory. I.e no need
to compile several versions of php anymore!
phpnotes at ssilk dot de
22-Oct-2002 04:36
To hand over the GET-variables
in interactive mode like in HTTP-Mode (e.g. your URI is
myprog.html?hugo=bla&bla=hugo), you have to call
php myprog.html '&hugo=bla&bla=hugo'
(two & instead of ? and &!)
There just a little difference in the $ARGC, $ARGV
values, but I think this is in those cases not relevant.
justin at visunet dot ie
21-Oct-2002 10:21
If you are trying to set up an
interactive command line script and you want to get
started straight away (works on 4+ I hope). Here is some
code to start you off:
<?php
set_time_limit(0);
define('STDIN',fopen("php://stdin","r"));
while(!0)
{
echo
"Select an option..\n\n";
echo " 1) Do
this\n";
echo " 2) Do
this\n";
echo " 3) Do
this\n";
echo " x) Exit\n";
switch(trim(fgets(STDIN,256)))
{
case 1:
break;
case 2:
break;
case 3:
break;
case "x":
exit();
default:
break;
}
}
fclose(STDIN);
?>
phpNOSPAM at dogpoop dot cjb dot net
11-Oct-2002 09:28
Here are some instructions on
how to make PHP files executable from the command prompt
in Win2k. I have not tested this in any other version
of Windows, but I'm assuming it will work in XP, but not
9x/Me.
There is an environment variable (control
panel->system->advanced->environment variables) named
PATHEXT. This is a list of file extensions Windows will
recognize as executable at the command prompt. Add .PHP
(or .PL, or .CLASS, or whatever) to this list. Windows
will use the default action associated with that file
type when you execute it from the command prompt.
To set up the default action:
Open Explorer.
Go to Tools->folder options->file types
Find the extension you're looking for. If it's not
there, click New to add it.
Click on the file type, then on Advanced, then New.
For the action, type "Run" or "Execute" or whatever
makes sense.
For the application, type
{path to application} "%1" %*
The %* will send any command line options that you type
to the program.
The application field for PHP might look like
c:\php\php.exe -f "%1" -- %*
(Note, you'll probably want to use the command line
interface version php-cli.exe)
or for Java
c:\java\java.exe "%1" %*
Click OK.
Click on the action that was just added, then click Set
default.
If this helps you or if you have any changes/more
information I would appreciate a note. Just remove
NOSPAM from the email address.
jeff at noSpam[] dot genhex dot net
06-Sep-2002 06:13
You can also call the script
from the command line after chmod'ing the file (ie:
chmod 755 file.php).
On your first line of the file, enter "#!/usr/bin/php"
(or to wherever your php executable is located). If you
want to suppress the PHP headers, use the line of
"#!/usr/bin/php -q" for your path.
zager[..A..T..]teleaction.de
15-Aug-2002 12:15
Under Solaris (at least 2.6) I
have some problems with reading stdin. Original pbms
report may be found here:
http://groups.google.com/groups?
q=Re:+%5BPHP%5D+Q+on+php://stdin+--+an+answer!&hl=en&lr=&ie=UTF-
8&oe=UTF-8&selm=3C74AF57.6090704%40Sun.COM&rnum=1
At a first glance the only solution for it is 'fgetcsv'
#!/usr/local/bin/php -q
<?php
set_magic_quotes_runtime(0);
$fd=fopen("php://stdin","r");
if (!$fd)
exit;
while (!feof
($fd))
{
$s
=
fgetcsv($fd,128,"\n");
if ($s==false)
continue;
echo $s[0]."\n";
}
?>
But... keep reading....
>>> I wrote
Hello,
Sometimes I hate PHP... ;)
Right today I was trapped by some strange bug in my code
with reading stdin using fgetcsv.
After a not small investigation I found that strings
like "foo\nboo\ndoo"goo\n (take note of double quatation
sign in it)
interpreted by fgetcsv like:
1->foo\nboo\ndoo
2->goo
since double quotation mark has a special meaning and
get stripped off of the input stream.
Indeed, according to PHP manual:
[quote]
array fgetcsv ( int fp, int length [, string delimiter
[, string enclosure]])
[skip]
another delimiter with the optional third parameter. _The_enclosure_character_is_double_quote_,_unless_
it_is_specified_.
[skip]
_enclosure_is_added_from_PHP 4.3.0. !!!!!!
[/quote]
Means no chance for us prior to 4.3.0 :(
But file() works just fine !!!! Of course by the price
of memory, so be careful with large files.
set_magic_quotes_runtime(0); // important, do not forget
it !!!
$s=file("php://stdin");
for ($i=0,$n=sizeof($s);$i<$n;$i++)
{
do_something_useful(rtrim($s[$i]));
}
Conclusion:
1. If you have no double quotation mark in your data use
fgetcsv
2. From 4.3.0 use fgetcsv($fd,"\n",""); // I hope it
will help
3. If you data is not huge use file("php://stdin");
Hope now it's cleared for 100% (to myself ;)
Good luck!
Dim
PS. Don't forget that it's only Solaris specific
problem. Under Linux just use usual fgets()...
jonNO at SPAMjellybob dot co dot uk
03-Aug-2002 10:17
If you want to get the output
of a command use the function shell_exec($command) - it
returns a string with the output of the command.
ben-php dot net at wefros dot com
13-Jun-2002 04:40
PHP 4.3 and above automatically
have STDOUT, STDIN, and STDERR openned ... but < 4.3.0
do not. This is how you make code that will work in
versions previous to PHP 4.3 and future versions without
any changes:
<?php
if (version_compare(phpversion(),'4.3.0','<'))
{
define('STDIN',fopen("php://stdin","r"));
define('STDOUT',fopen("php://stout","r"));
define('STDERR',fopen("php://sterr","r"));
register_shutdown_function(
create_function(
''
,
'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return
true;' ) );
}
$str
=
fgets(STDIN,256);
?>
pyxl at jerrell dot com
18-Feb-2002 12:52
Assuming
--prefix=/usr/local/php, it's better to create a symlink
from /usr/bin/php or /usr/local/bin/php to target
/usr/local/php/bin/php so that it's both in your path
and automatically correct every time you rebuild. If
you forgot to do that copy of the binary after a
rebuild, you can do all kinds of wild goose chasing when
things break.
Last updated:
August 15, 2009