To experiment on performance of pass-by-reference and pass-by-value, I used this script. Conclusions are below.
3 valuue yes 129 s 4 reference yes 66 us
1. PHP is already smart about zero-copy / copy-on-write. A function call does NOT copy the data unless it needs to; the data is only copied on write. That’s why #1 and #2 take similar times, whereas #3 takes 2 million times longer than #4. [You never need to use &$array to ask the compiler to do a zero-copy optimisation; it can work that out for itself.]
2. You do use &$array to tell the compiler «it is OK for the function to over-write my argument in place, I don’t need the original any more.» This can make a huge difference to performance when we have large amounts of memory to copy. (This is the only way it is done in C, arrays are always passed as pointers)
3. The other use of & is as a way to specify where data should be *returned*. (e.g. as used by exec() ). (This is a C-like way of passing pointers for outputs, whereas PHP functions normally return complex types, or multiple answers in an array)
5. Sometimes, pass by reference could be at the choice of the caller, NOT the function definitition. PHP doesn’t allow it, but it would be meaningful for the caller to decide to pass data in as a reference. i.e. «I’m done with the variable, it’s OK to stomp on it in memory». */ ?>
A function’s argument that is an object, will have its properties modified by the function although you don’t need to pass it by reference.
In function calls, PHP clearly distinguishes between missing arguments and present but empty arguments. Thus:
The best approach, it seems to me, is to always use a sentinel like null as the default value of an optional argument. This way, callers like g and g’s clients have many options, and furthermore, callers always know how to omit arguments so they can omit one in the middle of the parameter list.
PASSING A «VARIABLE-LENGTH ARGUMENT LIST OF REFERENCES» TO A FUNCTION As of PHP 5, Call-time pass-by-reference has been deprecated, this represents no problem in most cases, since instead of calling a function like this: myfunction($arg1, &$arg2, &$arg3);
provided you have defined your function as function myfuncion($a1, &$a2, &$a3) < // so &$a2 and &$a3 are // declared to be refs. . >
In the following code I tried to amend this by using the array() language-construct as the actual argument in the call to the function.
Запустить PHP в интерактивном режиме. Для получения дополнительной информации смотрите раздел Интерактивная консоль.
Путь связывания библиотек (Bind Path) для внешнего режима FASTCGI Server (только для CGI ).
Не менять текущую директорию на директорию скрипта (только для CGI ).
Тихий режим. Подавляет вывод заголовков HTTP (только для CGI ).
Измерить время выполнения скрипта, повторенного count раз (только для CGI ).
Если эта опция не указана, поиск php.ini будет осуществлён в местах по умолчанию.
Включить режим расширенной информации, используемый отладчиком/профайлером.
Пример #1 Вывод встроенных (и загруженных) модулей PHP и Zend
При использовании этого ключа следует быть очень осторожным и избегать недоразумений, связанных с автоматической подстановкой переменных окружения.
Пример #2 Ошибка синтаксиса при использовании двойных кавычек
Пример #3 Использование одинарных кавычек для предотвращения подстановки переменных в консоли
При использовании оболочки, отличной от sh/bash, могут возникнуть другие проблемы. В таком случае необходимо создать отчёт о возникшей ошибке на сайте » https://bugs.php.net/. Можно столкнуться с проблемами при попытке получить доступ к переменным оболочки или при работе с экранирующими обратными слешами. Теперь вы предупреждены!
Эта опция предназначена только для самого простого кода. Поэтому некоторые конфигурационные директивы (например, auto_prepend_file и auto_append_file) в этом режиме будут проигнорированы.
Выполняемый код PHP перед обработкой потока ввода (stdin).
PHP-код, выполняемый для каждой строки ввода.
PHP-файл, выполняемый для каждой строки ввода.
PHP-код, выполняемый после обработки ввода.
Показать исходный код с подсветкой синтаксиса.
Эта опция использует внутренний механизм для разбора файла и записи в стандартный поток вывода подсвеченной версии этого файла. Учтите, что все что она делает, это генерирует блок [. ] HTML-тегов, без HTML-заголовков.
Показать исходный код без комментариев и пробелов.
Загружает модуль Zend. Если передано только имя файла, PHP попытается загрузить этот модуль из пути библиотек по умолчанию (обычно указывается в /etc/ld.so.conf в системах Linux). Передача файла с абсолютным путём не будет использовать системный путь поиска библиотеки. Относительное имя файла, содержащее директорию, укажет PHP подгрузить модуль относительно текущей директории.
Показывает имена конфигурационных файлов и отсканированные директории.
Показывает информацию об указанной функции или методе класса (например, количество и названия параметров).
Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.
Показывает информацию об указанном классе (список констант, свойств и методов).
Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.
Эта опция доступна только в том случае, если PHP был скомпилирован с поддержкой Reflection.
Показывает информацию о конфигурации указанного Zend-модуля (та же информация, которая возвращается phpinfo() ).
Показывает информацию о конфигурации указанного модуля (та же информация, которая возвращается phpinfo() ). Конфигурацию ядра можно узнать, указав в качестве имени модуля значение «main».
User Contributed Notes 2 notes
If however, the html code in the page is: the picture displays correctly.
Hence relative addressing is broken in PHP 5.4.33 Win32 VC9 build.
It behaves exactly like you’d expect with cgi-php.
Even better, instead of putting that line in every file, take advantage of PHP’s auto_prepend_file directive. Put that line in its own file and set the auto_prepend_file directive in your cli-specific php.ini like so:
It will be automatically prepended to any PHP file run from the command line.
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:
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:
I noticed this somehow got ommited from the docs, hope it helps someone!
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.
Parsing commandline argument GET String without changing the PHP script (linux shell): URL: index.php?a=1&b=2 Result: output.html
(no need to change php.ini)
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
If you want to be interactive with the user and accept user input, all you need to do is read from stdin.
Parsing command line: optimization is evil!
One thing all contributors on this page forgotten is that you can suround an argv with single or double quotes. So the join coupled together with the preg_match_all will always break that 🙂
/* vim: set expandtab tabstop=2 shiftwidth=2: */ ?>
i use emacs in c-mode for editing. in 4.3, starting a cli script like so:
Just another variant of previous script that group arguments doesn’t starts with ‘-‘ or ‘—‘
If you edit a php file in windows, upload and run it on linux with command line method. You may encounter a running problem probably like that:
Or you may encounter some other strange problem. Care the enter key. In windows environment, enter key generate two binary characters ‘0D0A’. But in Linux, enter key generate just only a ‘OA’. I wish it can help someone if you are using windows to code php and run it as a command line program on linux.
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.
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).
// 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
// 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 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);
// 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];
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
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.
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.
And you did, of course, remember to add the php command as the first line of your script, yeah? Of course.
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:
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!
You can also call the script from the command line after chmod’ing the file (ie: chmod 755 file.php).
Adding a pause() function to PHP waiting for any user input returning it:
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’
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.
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.
In the above example, you would use: #!/usr/local/bin/php
I was looking for a way to interactively get a single character response from user. Using STDIN with fread, fgets and such will only work after pressing enter. So I came up with this instead:
For example you can do this code:
This will just output each line of the input file without doing anything to it.
Вот как обычно бывает: Нам нужно написать малюсенький консольный скрипт бекапа, который, может запускаться из крона, и при этом скрипт должен принимать параметры для соединения с базой данных.
Функции argv и argc
Самое простейшее что мы начнём писать будет выглядеть примерно так:
Тут мы использовали системную переменную argс для получения количества всех параметров. Запомните, что нулевой параметр (имя скрипта) тут тоже учитывается.
И системную переменную argv с массивом всех параметров.
Для простейшего скрипта этого хватит, но что если мы захотим поддерживать и отдать этот скрипт другим разработчикам?
Скорее всего будет куча ругани в нашу сторону, потому что очень легко можно ошибиться и перепутать местами пароль и базу данных и заметить ошибку будет крайне сложно. Посмотрите:
Разбираем параметры с функцией getopt
Вот тут нам на помощь приходит крайне удобная функция разбора параметров: getopt
Основная мощь getopt в том, что она позволяет нам использовать флаги, обязательные и необязательные параметры в произвольном порядке.
Давайте напишем простой, но очень выразительный пример использования getopt, а потом, посмотрите как люди раньше мучались с регулярками, что бы разобрать командную строку 🙂
Теперь запустим наш скрипт с параметром –help и порадуемся что хорошо поддерживаемую и понятную программу так легко написать
Давайте ещё добавим последний штрих, который должен быть во всех наших скриптах: 1. Можно убрать расширение php 2. В начало каждого скрипта добавим опцию для интерпритатора #!/usr/bin/env php 3. Сделаем наши скрипты исполняемыми chmod +x backup.php
После этого можно пользоваться получившимся скриптом как настоящей юникс-программой:
PHP has the getopt() function for getting options or command line arguments from a CLI PHP script. This provides a simple way to get values from the command line like e.g. “-a foo”. This post looks at how to do this. More details can be found in the PHP getopt() manual page.
$_SERVER[‘argv’]
getopt() function
If you called the script like this (the first example has spaces between the flag and the value, the second has no spaces but both will return the values):
Then doing print_r($arguments) would return this:
Note that the colons after the value are required; if you don’t use them and a flag is passed on the command line with that letter then it won’t be returned in the array.
and then doing print_r($arguments) would show this:
Version used for this post
The version I used for testing with this post was PHP 5.1.6 on CentOS 5.0. According to the PHP manual page for getopt() on versions of PHP prior to 5.3 did not work. There is also an “optional” parameters option from 5.3 which doesn’t work as expected in the version 5.1.6 that I used, and a second parameter to the getopt() function for long options (in the style –name=value or –name value) which is not widely available prior to 5.3. On the CentOS system I was using, attempting to use the second paameter for long options resulted in this error message:
Therefore if you are targeting systems with PHP installations prior to 5.3 you are best to stick with the short options only.