diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..68136ed --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Declare files that will always have LF line endings on checkout. +php-fpm-cli text eol=lf \ No newline at end of file diff --git a/README.md b/README.md index d92e28c..ed1f792 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ # php-fpm-cli -Running PHP-FPM, especially for website hosts using NGINX, is missing an important functionality to execute PHP scripts directly from the command-line. +Running PHP-FPM, especially for website hosts using NGINX, is missing the important ability to execute PHP scripts directly from the command-line while simulating the website context. -With this simple script, one can execute PHP scripts directly from CLI. It is convenient to test PHP in CLI, run batch operations with PHP and for cronjobs. +With this simple script, one can execute PHP scripts that are normally called via PHP-FPM, directly from CLI. This can be used for testing, batch operations, or cronjobs. -This script is based on [Mathias Leppich's gist][1], with added support for loading the script from a file (instead of input code as CLI argument), query-string parameters and verification of not only the exit code of the script - but also http-status-code. +This script is based on [Mathias Leppich's gist][1], with added support for: +* loading the script from a file (instead of input code as CLI argument) +* query-string parameters +* verification of not only the exit code of the script, but also http-status-code. +* guessing of `$_SERVER` variables given a URL to simulate -See more details in: https://elisegev.medium.com/running-php-fpm-in-cli-e1f0f4b4f59a +See more details in [this Medium post](https://elisegev.medium.com/running-php-fpm-in-cli-e1f0f4b4f59a). ## Requirements @@ -24,7 +28,7 @@ apt-get install libfcgi0ldbl ### Setup -PHP script needs to be executable and owned by an allowed user (ACL): +The PHP script being executed needs to be executable and owned by an user allowed by the PHP-FPM configuration, so you may need to update it: ```shell script vi /etc/php-fpm.d/www.conf # add your ACL user to the comma-delimited list: listen.acl_users @@ -34,19 +38,29 @@ systemctl restart php-fpm ## Usage -Run PHP script: +The script will send the given PHP file to the PHP-FPM process and echo the response to STDOUT. + ```shell script -./php-fqm-cli -f +./php-fpm-cli -f -q "" [-connect ] [-m ] [-u ] ``` -Run PHP script with query params: +Parameters: +| Flag | Description | Default | Example | +| ---- | ----------- | ------- | ------- | +| `-f` | Path to the PHP file | | `/var/www/html/index.php` | +| `-connect` | PHP-FPM host and port, or path to a socket | `/run/php-fpm/www.sock` | `127.0.0.1:9000` | +| `-m` | Request method, GET or POST | GET | | +| `-u` | URL to simulate. This must return an status code 200, so make sure this is the canonical URL (i.e., it will not redirect) | | `https://www.mydomain.com/` | + + +Using query parameters: ```shell script -./php-fqm-cli -f -q "" +./php-fpm-cli -f myscript.php -q "param1=val1¶m2=val2" ``` -Example: +Using a URL: ```shell script -./php-fqm-cli -f myscript.php -q "param1=val1¶m2=val2" +./php-fpm-cli -f /var/www/html/index.php -connect 127.0.0.1:9000 -u https://www.mydomain.com/ ``` [1]: https://gist.github.com/muhqu/91497df3a110f594b992 \ No newline at end of file diff --git a/php-fpm-cli b/php-fpm-cli old mode 100644 new mode 100755 index 2569068..e88121a --- a/php-fpm-cli +++ b/php-fpm-cli @@ -32,7 +32,16 @@ Options: -f Run PHP file without using script tags - -q query string for running the php file + -q Query string for running the php file + + -m request method + Default: GET + + -u Full URL to simulate; this will try to set $_SERVER variables appropriately. + Only PHP files directly under the document root are currently supported. + You may need to include "/index.php" since we don't have use of Apache + RewriteRules. + example: https://www.mydomain.com/index.php USAGE } @@ -40,10 +49,50 @@ USAGE main() { res=0 + if [ -n $PHP_URL ] + then + # URL parsing code from https://stackoverflow.com/a/6174447/1282424 + + # extract the protocol + proto="$(echo $PHP_URL | grep :// | sed -e's,^\(.*://\).*,\1,g')" + + if [[ $proto =~ https ]] + then + https="on" + fi; + + # remove the protocol -- updated + url_no_proto=$(echo $PHP_URL | sed -e s,$proto,,g) + + # extract the user (if any) + user="$(echo $url_no_proto | grep @ | cut -d@ -f1)" + + # extract the host and port -- updated + hostport=$(echo $url_no_proto | sed -e s,$user@,,g | cut -d/ -f1) + + # by request host without port + host="$(echo $hostport | sed -e 's,:.*,,g')" + + # by request - try to extract the port + port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')" + + # extract the path (if any) + path="$(echo $url_no_proto | grep / | cut -d/ -f2-)" + + # Assume the document root is the directory containing $PHP_FILE_PATH + document_root=`dirname $PHP_FILE_PATH` + fi; + #Execute PHP + SCRIPT_NAME=/$path \ + DOCUMENT_ROOT=$document_root \ + HTTP_HOST=$host \ + SERVER_NAME=$host \ + REQUEST_URI=/$path \ SCRIPT_FILENAME=$PHP_FILE_PATH \ + HTTPS=$https \ QUERY_STRING=$PHP_QUERY_STRING \ - REQUEST_METHOD=GET \ + REQUEST_METHOD=$PHP_REQUEST_METHOD \ cgi-fcgi -bind -connect "$CONN" > $TMP_OUTPUT_FILE_PATH #without dumping to file, cgi-fcgi hides "Status" #Get successful-execution indications @@ -68,6 +117,8 @@ main() { CONN="/run/php-fpm/www.sock" PHP_FILE_PATH="" PHP_QUERY_STRING="" +PHP_URL="" +PHP_REQUEST_METHOD="GET" TMP_OUTPUT_FILE_PATH="/tmp/php_fpm_cli_output.tmp" init() { until [ -z "$1" ]; do @@ -78,6 +129,10 @@ init() { -q) shift; PHP_QUERY_STRING="$1"; shift; ;; + -m) shift; PHP_REQUEST_METHOD="$1"; shift; ;; + + -u) shift; PHP_URL="$1"; shift; ;; + help|-h|-help|--help) usage; exit 0 diff --git a/php-fpm-cli.code-workspace b/php-fpm-cli.code-workspace new file mode 100644 index 0000000..876a149 --- /dev/null +++ b/php-fpm-cli.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file