summaryrefslogtreecommitdiff
path: root/sapi/cli/tests
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/cli/tests')
-rw-r--r--sapi/cli/tests/001.phpt19
-rw-r--r--sapi/cli/tests/002-win32.phpt22
-rw-r--r--sapi/cli/tests/002.phpt22
-rw-r--r--sapi/cli/tests/003-2.phpt25
-rw-r--r--sapi/cli/tests/003.phpt32
-rw-r--r--sapi/cli/tests/004.phpt34
-rw-r--r--sapi/cli/tests/005.phpt104
-rw-r--r--sapi/cli/tests/006.phpt140
-rw-r--r--sapi/cli/tests/007.phpt52
-rw-r--r--sapi/cli/tests/008.phpt43
-rw-r--r--sapi/cli/tests/009.phpt20
-rw-r--r--sapi/cli/tests/010-2.phpt35
-rw-r--r--sapi/cli/tests/010.phpt46
-rw-r--r--sapi/cli/tests/011.phpt58
-rw-r--r--sapi/cli/tests/012.phpt38
-rw-r--r--sapi/cli/tests/013.phpt34
-rw-r--r--sapi/cli/tests/014.phpt44
-rw-r--r--sapi/cli/tests/015.phpt35
-rw-r--r--sapi/cli/tests/016.phpt130
-rw-r--r--sapi/cli/tests/017.phpt106
-rw-r--r--sapi/cli/tests/018.phpt27
-rw-r--r--sapi/cli/tests/019.phpt36
-rw-r--r--sapi/cli/tests/020.phpt32
-rw-r--r--sapi/cli/tests/021.phpt43
-rw-r--r--sapi/cli/tests/022.inc14
-rw-r--r--sapi/cli/tests/022.phpt47
-rw-r--r--sapi/cli/tests/bug43177.phpt82
-rw-r--r--sapi/cli/tests/bug44564.phpt22
-rw-r--r--sapi/cli/tests/bug61546.phpt31
-rw-r--r--sapi/cli/tests/bug61679.phpt43
-rw-r--r--sapi/cli/tests/bug61977.phpt55
-rw-r--r--sapi/cli/tests/php_cli_server.inc62
-rw-r--r--sapi/cli/tests/php_cli_server_001.phpt16
-rw-r--r--sapi/cli/tests/php_cli_server_002.phpt20
-rw-r--r--sapi/cli/tests/php_cli_server_003.phpt18
-rw-r--r--sapi/cli/tests/php_cli_server_004.phpt48
-rw-r--r--sapi/cli/tests/php_cli_server_005.phpt71
-rw-r--r--sapi/cli/tests/php_cli_server_006.phpt42
-rw-r--r--sapi/cli/tests/php_cli_server_007.phpt40
-rw-r--r--sapi/cli/tests/php_cli_server_008.phpt68
-rw-r--r--sapi/cli/tests/php_cli_server_009.phpt93
-rw-r--r--sapi/cli/tests/php_cli_server_010.phpt75
-rw-r--r--sapi/cli/tests/php_cli_server_011.phpt41
-rw-r--r--sapi/cli/tests/php_cli_server_012.phpt55
-rw-r--r--sapi/cli/tests/php_cli_server_013.phpt108
-rw-r--r--sapi/cli/tests/php_cli_server_014.phpt80
-rw-r--r--sapi/cli/tests/php_cli_server_015.phpt49
-rw-r--r--sapi/cli/tests/php_cli_server_016.phpt46
-rw-r--r--sapi/cli/tests/php_cli_server_017.phpt44
-rw-r--r--sapi/cli/tests/php_cli_server_018.phpt44
-rw-r--r--sapi/cli/tests/skipif.inc7
51 files changed, 2498 insertions, 0 deletions
diff --git a/sapi/cli/tests/001.phpt b/sapi/cli/tests/001.phpt
new file mode 100644
index 0000000..6fbd608
--- /dev/null
+++ b/sapi/cli/tests/001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+version string
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n -v`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(%d) "PHP %s (cli) (built: %s)%s
+Copyright (c) 1997-20%d The PHP Group
+Zend Engine v%s, Copyright (c) 1998-20%d Zend Technologies
+"
+Done
diff --git a/sapi/cli/tests/002-win32.phpt b/sapi/cli/tests/002-win32.phpt
new file mode 100644
index 0000000..5a00c67
--- /dev/null
+++ b/sapi/cli/tests/002-win32.phpt
@@ -0,0 +1,22 @@
+--TEST--
+running code with -r
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) != 'WIN') {
+ die ("skip only for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n -r "var_dump('hello');"`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(18) "string(5) "hello"
+"
+Done
diff --git a/sapi/cli/tests/002.phpt b/sapi/cli/tests/002.phpt
new file mode 100644
index 0000000..be2b633
--- /dev/null
+++ b/sapi/cli/tests/002.phpt
@@ -0,0 +1,22 @@
+--TEST--
+running code with -r
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n -r 'var_dump("hello");'`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(18) "string(5) "hello"
+"
+Done
diff --git a/sapi/cli/tests/003-2.phpt b/sapi/cli/tests/003-2.phpt
new file mode 100644
index 0000000..2ed9b07
--- /dev/null
+++ b/sapi/cli/tests/003-2.phpt
@@ -0,0 +1,25 @@
+--TEST--
+defining INI options with -d (as 2nd arg)
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`"$php" -nd max_execution_time=111 -r 'var_dump(ini_get("max_execution_time"));'`);
+var_dump(`"$php" -nd max_execution_time=500 -r 'var_dump(ini_get("max_execution_time"));'`);
+
+?>
+===DONE===
+--EXPECTF--
+string(16) "string(3) "111"
+"
+string(16) "string(3) "500"
+"
+===DONE===
diff --git a/sapi/cli/tests/003.phpt b/sapi/cli/tests/003.phpt
new file mode 100644
index 0000000..d62360e
--- /dev/null
+++ b/sapi/cli/tests/003.phpt
@@ -0,0 +1,32 @@
+--TEST--
+defining INI options with -d
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n -d max_execution_time=111 -r 'var_dump(ini_get("max_execution_time"));'`);
+var_dump(`$php -n -d max_execution_time=500 -r 'var_dump(ini_get("max_execution_time"));'`);
+var_dump(`$php -n -d max_execution_time=500 -d max_execution_time=555 -r 'var_dump(ini_get("max_execution_time"));'`);
+var_dump(`$php -n -d upload_tmp_dir=/test/path -d max_execution_time=555 -r 'var_dump(ini_get("max_execution_time")); var_dump(ini_get("upload_tmp_dir"));'`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(16) "string(3) "111"
+"
+string(16) "string(3) "500"
+"
+string(16) "string(3) "555"
+"
+string(40) "string(3) "555"
+string(10) "/test/path"
+"
+Done
diff --git a/sapi/cli/tests/004.phpt b/sapi/cli/tests/004.phpt
new file mode 100644
index 0000000..378515d
--- /dev/null
+++ b/sapi/cli/tests/004.phpt
@@ -0,0 +1,34 @@
+--TEST--
+show information about function
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (!extension_loaded("reflection")) {
+ die("skip reflection extension required");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n --rf unknown`);
+var_dump(`$php -n --rf echo`);
+var_dump(`$php -n --rf phpinfo`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(45) "Exception: Function unknown() does not exist
+"
+string(42) "Exception: Function echo() does not exist
+"
+string(119) "Function [ <internal:standard> function phpinfo ] {
+
+ - Parameters [1] {
+ Parameter #0 [ <optional> $what ]
+ }
+}
+
+"
+Done
diff --git a/sapi/cli/tests/005.phpt b/sapi/cli/tests/005.phpt
new file mode 100644
index 0000000..84b0f98
--- /dev/null
+++ b/sapi/cli/tests/005.phpt
@@ -0,0 +1,104 @@
+--TEST--
+show information about class
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (!extension_loaded("reflection")) {
+ die("skip reflection extension required");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`"$php" -n --rc unknown`);
+var_dump(`"$php" -n --rc stdclass`);
+var_dump(`"$php" -n --rc exception`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(40) "Exception: Class unknown does not exist
+"
+string(183) "Class [ <internal:Core> class stdClass ] {
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [0] {
+ }
+
+ - Methods [0] {
+ }
+}
+
+"
+string(1355) "Class [ <internal:Core> class Exception ] {
+
+ - Constants [0] {
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [0] {
+ }
+
+ - Properties [7] {
+ Property [ <default> protected $message ]
+ Property [ <default> private $string ]
+ Property [ <default> protected $code ]
+ Property [ <default> protected $file ]
+ Property [ <default> protected $line ]
+ Property [ <default> private $trace ]
+ Property [ <default> private $previous ]
+ }
+
+ - Methods [10] {
+ Method [ <internal:Core> final private method __clone ] {
+ }
+
+ Method [ <internal:Core, ctor> public method __construct ] {
+
+ - Parameters [3] {
+ Parameter #0 [ <optional> $message ]
+ Parameter #1 [ <optional> $code ]
+ Parameter #2 [ <optional> $previous ]
+ }
+ }
+
+ Method [ <internal:Core> final public method getMessage ] {
+ }
+
+ Method [ <internal:Core> final public method getCode ] {
+ }
+
+ Method [ <internal:Core> final public method getFile ] {
+ }
+
+ Method [ <internal:Core> final public method getLine ] {
+ }
+
+ Method [ <internal:Core> final public method getTrace ] {
+ }
+
+ Method [ <internal:Core> final public method getPrevious ] {
+ }
+
+ Method [ <internal:Core> final public method getTraceAsString ] {
+ }
+
+ Method [ <internal:Core> public method __toString ] {
+ }
+ }
+}
+
+"
+Done
diff --git a/sapi/cli/tests/006.phpt b/sapi/cli/tests/006.phpt
new file mode 100644
index 0000000..3d5c916
--- /dev/null
+++ b/sapi/cli/tests/006.phpt
@@ -0,0 +1,140 @@
+--TEST--
+show information about extension
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (!extension_loaded("reflection") || !extension_loaded("session")) {
+ die("skip reflection and session extensions required");
+}
+?>
+--INI--
+date.timezone=
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n --re unknown`);
+var_dump(`$php -n --re ""`);
+var_dump(`$php -n --re pcre`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(44) "Exception: Extension unknown does not exist
+"
+string(37) "Exception: Extension does not exist
+"
+string(%d) "Extension [ <persistent> extension #%d pcre version <no_version> ] {
+
+ - INI {
+ Entry [ pcre.backtrack_limit <ALL> ]
+ Current = '%d'
+ }
+ Entry [ pcre.recursion_limit <ALL> ]
+ Current = '%d'
+ }
+ }
+
+ - Constants [14] {
+ Constant [ integer PREG_PATTERN_ORDER ] { 1 }
+ Constant [ integer PREG_SET_ORDER ] { 2 }
+ Constant [ integer PREG_OFFSET_CAPTURE ] { 256 }
+ Constant [ integer PREG_SPLIT_NO_EMPTY ] { 1 }
+ Constant [ integer PREG_SPLIT_DELIM_CAPTURE ] { 2 }
+ Constant [ integer PREG_SPLIT_OFFSET_CAPTURE ] { 4 }
+ Constant [ integer PREG_GREP_INVERT ] { 1 }
+ Constant [ integer PREG_NO_ERROR ] { 0 }
+ Constant [ integer PREG_INTERNAL_ERROR ] { 1 }
+ Constant [ integer PREG_BACKTRACK_LIMIT_ERROR ] { 2 }
+ Constant [ integer PREG_RECURSION_LIMIT_ERROR ] { 3 }
+ Constant [ integer PREG_BAD_UTF8_ERROR ] { 4 }
+ Constant [ integer PREG_BAD_UTF8_OFFSET_ERROR ] { 5 }
+ Constant [ string PCRE_VERSION ] { %s }
+ }
+
+ - Functions {
+ Function [ <internal:pcre> function preg_match ] {
+
+ - Parameters [5] {
+ Parameter #0 [ <required> $pattern ]
+ Parameter #1 [ <required> $subject ]
+ Parameter #2 [ <optional> &$subpatterns ]
+ Parameter #3 [ <optional> $flags ]
+ Parameter #4 [ <optional> $offset ]
+ }
+ }
+ Function [ <internal:pcre> function preg_match_all ] {
+
+ - Parameters [5] {
+ Parameter #0 [ <required> $pattern ]
+ Parameter #1 [ <required> $subject ]
+ Parameter #2 [ <optional> &$subpatterns ]
+ Parameter #3 [ <optional> $flags ]
+ Parameter #4 [ <optional> $offset ]
+ }
+ }
+ Function [ <internal:pcre> function preg_replace ] {
+
+ - Parameters [5] {
+ Parameter #0 [ <required> $regex ]
+ Parameter #1 [ <required> $replace ]
+ Parameter #2 [ <required> $subject ]
+ Parameter #3 [ <optional> $limit ]
+ Parameter #4 [ <optional> &$count ]
+ }
+ }
+ Function [ <internal:pcre> function preg_replace_callback ] {
+
+ - Parameters [5] {
+ Parameter #0 [ <required> $regex ]
+ Parameter #1 [ <required> $callback ]
+ Parameter #2 [ <required> $subject ]
+ Parameter #3 [ <optional> $limit ]
+ Parameter #4 [ <optional> &$count ]
+ }
+ }
+ Function [ <internal:pcre> function preg_filter ] {
+
+ - Parameters [5] {
+ Parameter #0 [ <required> $regex ]
+ Parameter #1 [ <required> $replace ]
+ Parameter #2 [ <required> $subject ]
+ Parameter #3 [ <optional> $limit ]
+ Parameter #4 [ <optional> &$count ]
+ }
+ }
+ Function [ <internal:pcre> function preg_split ] {
+
+ - Parameters [4] {
+ Parameter #0 [ <required> $pattern ]
+ Parameter #1 [ <required> $subject ]
+ Parameter #2 [ <optional> $limit ]
+ Parameter #3 [ <optional> $flags ]
+ }
+ }
+ Function [ <internal:pcre> function preg_quote ] {
+
+ - Parameters [2] {
+ Parameter #0 [ <required> $str ]
+ Parameter #1 [ <optional> $delim_char ]
+ }
+ }
+ Function [ <internal:pcre> function preg_grep ] {
+
+ - Parameters [3] {
+ Parameter #0 [ <required> $regex ]
+ Parameter #1 [ <required> $input ]
+ Parameter #2 [ <optional> $flags ]
+ }
+ }
+ Function [ <internal:pcre> function preg_last_error ] {
+
+ - Parameters [0] {
+ }
+ }
+ }
+}
+
+"
+Done
diff --git a/sapi/cli/tests/007.phpt b/sapi/cli/tests/007.phpt
new file mode 100644
index 0000000..0bf4070
--- /dev/null
+++ b/sapi/cli/tests/007.phpt
@@ -0,0 +1,52 @@
+--TEST--
+strip comments and whitespace with -w
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = dirname(__FILE__).'/007.test.php';
+$code ='
+<?php
+/* some test script */
+
+class test { /* {{{ */
+ public $var = "test"; //test var
+#perl style comment
+ private $pri; /* private attr */
+
+ function foo(/* void */) {
+ }
+}
+/* }}} */
+
+?>
+';
+
+file_put_contents($filename, $code);
+
+var_dump(`$php -n -w "$filename"`);
+var_dump(`$php -n -w "wrong"`);
+var_dump(`echo "<?php /* comment */ class test {\n // comment \n function foo() {} } ?>" | $php -n -w`);
+
+@unlink($filename);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(81) "
+<?php
+ class test { public $var = "test"; private $pri; function foo() { } } ?>
+"
+string(33) "Could not open input file: wrong
+"
+string(43) "<?php class test { function foo() {} } ?>
+"
+Done
diff --git a/sapi/cli/tests/008.phpt b/sapi/cli/tests/008.phpt
new file mode 100644
index 0000000..e14338f
--- /dev/null
+++ b/sapi/cli/tests/008.phpt
@@ -0,0 +1,43 @@
+--TEST--
+execute a file with -f
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = dirname(__FILE__).'/008.test.php';
+$code ='
+<?php
+
+class test {
+ private $pri;
+}
+
+var_dump(test::$pri);
+?>
+';
+
+file_put_contents($filename, $code);
+
+var_dump(`$php -n -f "$filename"`);
+var_dump(`$php -n -f "wrong"`);
+
+@unlink($filename);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(%d) "
+
+Fatal error: Cannot access private property test::$pri in %s on line %d
+"
+string(33) "Could not open input file: wrong
+"
+Done
diff --git a/sapi/cli/tests/009.phpt b/sapi/cli/tests/009.phpt
new file mode 100644
index 0000000..33f859f
--- /dev/null
+++ b/sapi/cli/tests/009.phpt
@@ -0,0 +1,20 @@
+--TEST--
+using invalid combinations of cmdline options
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`$php -n -a -r "echo hello;"`);
+var_dump(`$php -n -r "echo hello;" -a`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(57) "Either execute direct code, process stdin or use a file.
+"
+string(57) "Either execute direct code, process stdin or use a file.
+"
+Done
diff --git a/sapi/cli/tests/010-2.phpt b/sapi/cli/tests/010-2.phpt
new file mode 100644
index 0000000..bd33d2c
--- /dev/null
+++ b/sapi/cli/tests/010-2.phpt
@@ -0,0 +1,35 @@
+--TEST--
+executing a code with -R
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename_txt = dirname(__FILE__)."/010.test.txt";
+
+$txt = '
+test
+hello
+';
+
+file_put_contents($filename_txt, $txt);
+
+var_dump(`cat "$filename_txt" | "$php" -n -R "var_dump(1);"`);
+
+@unlink($filename_txt);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(21) "int(1)
+int(1)
+int(1)
+"
+Done
diff --git a/sapi/cli/tests/010.phpt b/sapi/cli/tests/010.phpt
new file mode 100644
index 0000000..77c76c1
--- /dev/null
+++ b/sapi/cli/tests/010.phpt
@@ -0,0 +1,46 @@
+--TEST--
+executing a file with -F
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = __DIR__."/010.test.php";
+$filename_txt = __DIR__."/010.test.txt";
+
+$code = '
+<?php
+var_dump(fread(STDIN, 10));
+?>
+';
+
+file_put_contents($filename, $code);
+
+$txt = '
+test
+hello';
+
+file_put_contents($filename_txt, $txt);
+
+var_dump(`cat "$filename_txt" | "$php" -n -F "$filename"`);
+
+?>
+===DONE===
+--CLEAN--
+<?php
+@unlink(__DIR__."/010.test.php");
+@unlink(__DIR__."/010.test.txt");
+?>
+--EXPECTF--
+string(25) "
+string(10) "test
+hello"
+"
+===DONE===
diff --git a/sapi/cli/tests/011.phpt b/sapi/cli/tests/011.phpt
new file mode 100644
index 0000000..6154693
--- /dev/null
+++ b/sapi/cli/tests/011.phpt
@@ -0,0 +1,58 @@
+--TEST--
+syntax check
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = dirname(__FILE__)."/011.test.php";
+
+$code = '
+<?php
+
+$test = "var";
+
+class test {
+ private $var;
+}
+
+echo test::$var;
+
+?>
+';
+
+file_put_contents($filename, $code);
+
+var_dump(`"$php" -n -l $filename`);
+var_dump(`"$php" -n -l some.unknown`);
+
+$code = '
+<?php
+
+class test
+ private $var;
+}
+
+?>
+';
+
+file_put_contents($filename, $code);
+
+var_dump(`"$php" -n -l $filename`);
+
+@unlink($filename);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(%d) "No syntax errors detected in %s011.test.php
+"
+string(40) "Could not open input file: some.unknown
+"
+string(%d) "
+Parse error: %s expecting %s{%s in %s on line %d
+Errors parsing %s011.test.php
+"
+Done
diff --git a/sapi/cli/tests/012.phpt b/sapi/cli/tests/012.phpt
new file mode 100644
index 0000000..c1e4f6a
--- /dev/null
+++ b/sapi/cli/tests/012.phpt
@@ -0,0 +1,38 @@
+--TEST--
+invalid arguments and error messages
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+var_dump(`"$php" -n -F some.php -F some.php`);
+var_dump(`"$php" -n -F some.php -R some.php`);
+var_dump(`"$php" -n -R some.php -F some.php`);
+var_dump(`"$php" -n -R some.php -R some.php`);
+var_dump(`"$php" -n -f some.php -f some.php`);
+var_dump(`"$php" -n -B '' -B ''`);
+var_dump(`"$php" -n -E '' -E ''`);
+var_dump(`"$php" -n -r '' -r ''`);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(32) "You can use -R or -F only once.
+"
+string(32) "You can use -R or -F only once.
+"
+string(32) "You can use -R or -F only once.
+"
+string(32) "You can use -R or -F only once.
+"
+string(26) "You can use -f only once.
+"
+string(26) "You can use -B only once.
+"
+string(26) "You can use -E only once.
+"
+string(26) "You can use -r only once.
+"
+Done
diff --git a/sapi/cli/tests/013.phpt b/sapi/cli/tests/013.phpt
new file mode 100644
index 0000000..99bfe5e
--- /dev/null
+++ b/sapi/cli/tests/013.phpt
@@ -0,0 +1,34 @@
+--TEST--
+running PHP code before and after processing input lines with -B and -E
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename_txt = dirname(__FILE__)."/013.test.txt";
+file_put_contents($filename_txt, "test\nfile\ncontents\n");
+
+var_dump(`cat "$filename_txt" | "$php" -n -B 'var_dump("start");'`);
+var_dump(`cat "$filename_txt" | "$php" -n -E 'var_dump("end");'`);
+var_dump(`cat "$filename_txt" | "$php" -n -B 'var_dump("start");' -E 'var_dump("end");'`);
+
+@unlink($filename_txt);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(18) "string(5) "start"
+"
+string(16) "string(3) "end"
+"
+string(34) "string(5) "start"
+string(3) "end"
+"
+Done
diff --git a/sapi/cli/tests/014.phpt b/sapi/cli/tests/014.phpt
new file mode 100644
index 0000000..e8c5203
--- /dev/null
+++ b/sapi/cli/tests/014.phpt
@@ -0,0 +1,44 @@
+--TEST--
+syntax highlighting
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = dirname(__FILE__)."/014.test.php";
+$code = '
+<?php
+$test = "var"; //var
+/* test class */
+class test {
+ private $var = array();
+
+ public static function foo(Test $arg) {
+ echo "hello";
+ var_dump($this);
+ }
+}
+
+$o = new test;
+?>
+';
+
+file_put_contents($filename, $code);
+
+var_dump(`"$php" -n -s $filename`);
+var_dump(`"$php" -n -s unknown`);
+
+@unlink($filename);
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(1478) "<code><span style="color: #000000">
+<br /><span style="color: #0000BB">&lt;?php<br />$test&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"var"</span><span style="color: #007700">;&nbsp;</span><span style="color: #FF8000">//var<br />/*&nbsp;test&nbsp;class&nbsp;*/<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">test&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">$var&nbsp;</span><span style="color: #007700">=&nbsp;array();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">Test&nbsp;$arg</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"hello"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000BB">$o&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">test</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;<br /></span>
+</span>
+</code>"
+string(35) "Could not open input file: unknown
+"
+Done
diff --git a/sapi/cli/tests/015.phpt b/sapi/cli/tests/015.phpt
new file mode 100644
index 0000000..ab5918b
--- /dev/null
+++ b/sapi/cli/tests/015.phpt
@@ -0,0 +1,35 @@
+--TEST--
+CLI long options
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+
+echo `"$php" -n --version | grep built:`;
+echo `echo "<?php print_r(\\\$argv);" | "$php" -n -- foo bar baz`, "\n";
+echo `"$php" -n --version foo bar baz | grep built:`;
+echo `"$php" -n --notexisting foo bar baz | grep Usage:`;
+
+echo "Done\n";
+?>
+--EXPECTF--
+PHP %d.%d.%d%s(cli) (built: %s)%s
+Array
+(
+ [0] => -
+ [1] => foo
+ [2] => bar
+ [3] => baz
+)
+
+PHP %d.%d.%d%s(cli) (built: %s)%s
+Usage: %s [options] [-f] <file> [--] [args...]
+Done
diff --git a/sapi/cli/tests/016.phpt b/sapi/cli/tests/016.phpt
new file mode 100644
index 0000000..31c1a40
--- /dev/null
+++ b/sapi/cli/tests/016.phpt
@@ -0,0 +1,130 @@
+--TEST--
+CLI -a and readline
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (!extension_loaded('readline') || readline_info('done') === NULL) {
+ die ("skip need readline support");
+}
+?>
+--FILE--
+<?php
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+// disallow console escape sequences that may break the output
+putenv('TERM=VT100');
+
+$codes = array();
+
+$codes[1] = <<<EOT
+echo 'Hello world';
+exit
+EOT;
+
+$codes[] = <<<EOT
+echo 'multine
+single
+quote';
+exit
+EOT;
+
+$codes[] = <<<EOT
+echo <<<HEREDOC
+Here
+comes
+the
+doc
+HEREDOC;
+EOT;
+
+$codes[] = <<<EOT
+if (0) {
+ echo "I'm not there";
+}
+echo "Done";
+EOT;
+
+$codes[] = <<<EOT
+function a_function_with_some_name() {
+ echo "I was called!";
+}
+a_function_w );
+EOT;
+
+foreach ($codes as $key => $code) {
+ echo "\n--------------\nSnippet no. $key:\n--------------\n";
+ $code = escapeshellarg($code);
+ echo `echo $code | "$php" -a`, "\n";
+}
+
+echo "\nDone\n";
+?>
+--XFAIL--
+https://bugs.php.net/bug.php?id=55496
+--EXPECTF--
+--------------
+Snippet no. 1:
+--------------
+Interactive shell
+
+php > echo 'Hello world';
+Hello world
+php > exit
+
+
+--------------
+Snippet no. 2:
+--------------
+Interactive shell
+
+php > echo 'multine
+php ' single
+php ' quote';
+multine
+single
+quote
+php > exit
+
+
+--------------
+Snippet no. 3:
+--------------
+Interactive shell
+
+php > echo <<<HEREDOC
+<<< > Here
+<<< > comes
+<<< > the
+<<< > doc
+<<< > HEREDOC;
+Here
+comes
+the
+doc
+php >
+
+--------------
+Snippet no. 4:
+--------------
+Interactive shell
+
+php > if (0) {
+php { echo "I'm not there";
+php { }
+php > echo "Done";
+Done
+php >
+
+--------------
+Snippet no. 5:
+--------------
+Interactive shell
+
+php > function a_function_with_some_name() {
+php { echo "I was called!";
+php { }
+php > a_function_with_some_name();
+I was called!
+php >
+
+Done
diff --git a/sapi/cli/tests/017.phpt b/sapi/cli/tests/017.phpt
new file mode 100644
index 0000000..efaf977
--- /dev/null
+++ b/sapi/cli/tests/017.phpt
@@ -0,0 +1,106 @@
+--TEST--
+CLI -a and libedit
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (!extension_loaded('readline') || readline_info('done') !== NULL) {
+ die ("skip need readline support using libedit");
+}
+?>
+--FILE--
+<?php
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$codes = array();
+
+$codes[1] = <<<EOT
+echo 'Hello world';
+exit
+EOT;
+
+$codes[] = <<<EOT
+echo 'multine
+single
+quote';
+exit
+EOT;
+
+$codes[] = <<<EOT
+echo <<<HEREDOC
+Here
+comes
+the
+doc
+HEREDOC;
+EOT;
+
+$codes[] = <<<EOT
+if (0) {
+ echo "I'm not there";
+}
+echo "Done";
+EOT;
+
+$codes[] = <<<EOT
+function a_function_with_some_name() {
+ echo "I was called!";
+}
+a_function_w );
+EOT;
+
+foreach ($codes as $key => $code) {
+ echo "\n--------------\nSnippet no. $key:\n--------------\n";
+ $code = escapeshellarg($code);
+ echo `echo $code | "$php" -a`, "\n";
+}
+
+echo "\nDone\n";
+?>
+--EXPECTF--
+--------------
+Snippet no. 1:
+--------------
+Interactive shell
+
+Hello world
+
+
+--------------
+Snippet no. 2:
+--------------
+Interactive shell
+
+multine
+single
+quote
+
+
+--------------
+Snippet no. 3:
+--------------
+Interactive shell
+
+Here
+comes
+the
+doc
+
+
+--------------
+Snippet no. 4:
+--------------
+Interactive shell
+
+Done
+
+
+--------------
+Snippet no. 5:
+--------------
+Interactive shell
+
+
+Parse error: syntax error, unexpected ')' in php shell code on line 1
+
+
+Done
diff --git a/sapi/cli/tests/018.phpt b/sapi/cli/tests/018.phpt
new file mode 100644
index 0000000..56921bd
--- /dev/null
+++ b/sapi/cli/tests/018.phpt
@@ -0,0 +1,27 @@
+--TEST--
+CLI php -m
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+
+echo `"$php" -n -m`;
+
+echo "Done\n";
+?>
+--EXPECTF--
+[PHP Modules]
+%a
+pcre
+%a
+
+[Zend Modules]
+%aDone
diff --git a/sapi/cli/tests/019.phpt b/sapi/cli/tests/019.phpt
new file mode 100644
index 0000000..c98155d
--- /dev/null
+++ b/sapi/cli/tests/019.phpt
@@ -0,0 +1,36 @@
+--TEST--
+CLI php -i
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+
+echo `"$php" -n -i`;
+
+echo "\nDone\n";
+?>
+--EXPECTF--
+phpinfo()
+PHP Version => %s
+%a
+PHP License
+This program is free software; you can redistribute it and/or modify
+it under the terms of the PHP License as published by the PHP Group
+and included in the distribution in the file: LICENSE
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+If you did not receive a copy of the PHP license, or have any
+questions about PHP licensing, please contact license@php.net.
+
+Done
diff --git a/sapi/cli/tests/020.phpt b/sapi/cli/tests/020.phpt
new file mode 100644
index 0000000..62be4ba
--- /dev/null
+++ b/sapi/cli/tests/020.phpt
@@ -0,0 +1,32 @@
+--TEST--
+CLI php --ri
+--SKIPIF--
+<?php
+include "skipif.inc";
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+
+echo `"$php" -n --ri this_extension_does_not_exist_568537753423`;
+echo `"$php" -n --ri standard`;
+
+echo "\nDone\n";
+?>
+--EXPECTF--
+Extension 'this_extension_does_not_exist_568537753423' not present.
+
+standard
+
+%a
+
+Directive => Local Value => Master Value
+%a
+
+Done
+
diff --git a/sapi/cli/tests/021.phpt b/sapi/cli/tests/021.phpt
new file mode 100644
index 0000000..2ddd688
--- /dev/null
+++ b/sapi/cli/tests/021.phpt
@@ -0,0 +1,43 @@
+--TEST--
+CLI shell shebang
+--SKIPIF--
+<?php
+include 'skipif.inc';
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die ("skip not for Windows");
+}
+
+if (strlen("#!".getenv('TEST_PHP_EXECUTABLE')) > 127) {
+ die ("skip shebang is too long, see http://www.in-ulm.de/~mascheck/various/shebang/#results");
+}
+?>
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+
+$filename = __DIR__.'/021.tmp.php';
+
+$script = "#!$php -n\n".
+ "ola\n".
+ "<?php echo 1+1,'\n';\n".
+ "?>\n".
+ "adeus\n";
+
+file_put_contents($filename, $script);
+chmod($filename, 0777);
+
+echo `$filename`;
+
+echo "\nDone\n";
+?>
+--CLEAN--
+<?php
+unlink(__DIR__.'/021.tmp.php');
+?>
+--EXPECTF--
+ola
+2
+adeus
+
+Done
diff --git a/sapi/cli/tests/022.inc b/sapi/cli/tests/022.inc
new file mode 100644
index 0000000..b77512f
--- /dev/null
+++ b/sapi/cli/tests/022.inc
@@ -0,0 +1,14 @@
+<?php
+
+ob_start();
+var_dump(STDIN);
+
+$fd = fopen("php://stdin","r");
+var_dump($fd);
+
+$client_socket = stream_socket_accept($fd);
+
+$data = ob_get_clean();
+fwrite($client_socket, $data);
+
+?>
diff --git a/sapi/cli/tests/022.phpt b/sapi/cli/tests/022.phpt
new file mode 100644
index 0000000..0110220
--- /dev/null
+++ b/sapi/cli/tests/022.phpt
@@ -0,0 +1,47 @@
+--TEST--
+STDIN/OUT/ERR stream type
+--SKIPIF--
+<?php
+if (!getenv("TEST_PHP_EXECUTABLE")) die("skip TEST_PHP_EXECUTABLE not set");
+if (substr(PHP_OS, 0, 3) == "WIN") die("skip non windows test");
+?>
+--FILE--
+<?php
+$php = getenv("TEST_PHP_EXECUTABLE");
+$socket_file = tempnam(sys_get_temp_dir(), pathinfo(__FILE__, PATHINFO_FILENAME) . '.sock');
+$test_file = dirname(__FILE__) . '/' . pathinfo(__FILE__, PATHINFO_FILENAME) . '.inc';
+if (file_exists($socket_file)) {
+ unlink($socket_file);
+}
+$socket = stream_socket_server('unix://' . $socket_file);
+var_dump($socket);
+if (!$socket) {
+ exit(1);
+}
+$desc = array(
+ 0 => $socket,
+ 1 => STDOUT,
+ 2 => STDERR,
+);
+$pipes = array();
+$proc = proc_open("$php -n " . escapeshellarg($test_file), $desc, $pipes);
+var_dump($proc);
+if (!$proc) {
+ exit(1);
+}
+
+$client_socket = stream_socket_client('unix://' . $socket_file);
+var_dump($client_socket);
+echo stream_get_contents($client_socket);
+fclose($client_socket);
+
+proc_terminate($proc);
+proc_close($proc);
+unlink($socket_file);
+?>
+--EXPECTF--
+resource(%d) of type (stream)
+resource(%d) of type (process)
+resource(%d) of type (stream)
+resource(%d) of type (stream)
+resource(%d) of type (stream)
diff --git a/sapi/cli/tests/bug43177.phpt b/sapi/cli/tests/bug43177.phpt
new file mode 100644
index 0000000..36b5504
--- /dev/null
+++ b/sapi/cli/tests/bug43177.phpt
@@ -0,0 +1,82 @@
+--TEST--
+Bug #61977 Test exit code for various errors
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'SCRIPT'
+ ini_set('display_errors', 0);
+ switch($_SERVER["REQUEST_URI"]) {
+ case "/parse":
+ eval("this is a parse error");
+ echo "OK\n";
+ break;
+ case "/fatal":
+ eval("foo();");
+ echo "OK\n";
+ break;
+ case "/compile":
+ eval("class foo { final private final function bar() {} }");
+ echo "OK\n";
+ break;
+ case "/fatal2":
+ foo();
+ echo "OK\n";
+ break;
+ default:
+ return false;
+ }
+SCRIPT
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+foreach(array("parse", "fatal", "fatal2", "compile") as $url) {
+ $fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+ if (!$fp) {
+ die("connect failed");
+ }
+
+ if(fwrite($fp, <<<HEADER
+GET /$url HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+ }
+}
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: localhost
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+OK
+HTTP/1.0 500 Internal Server Error
+Host: localhost
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+HTTP/1.0 500 Internal Server Error
+Host: localhost
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+HTTP/1.0 500 Internal Server Error
+Host: localhost
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
diff --git a/sapi/cli/tests/bug44564.phpt b/sapi/cli/tests/bug44564.phpt
new file mode 100644
index 0000000..7dca62a
--- /dev/null
+++ b/sapi/cli/tests/bug44564.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #44564 (escapeshellarg removes UTF-8 multi-byte characters)
+--SKIPIF--
+<?php
+if (false == setlocale(LC_CTYPE, "UTF8", "en_US.UTF-8")) {
+ die("skip setlocale() failed\n");
+}
+?>
+--FILE--
+<?php
+setlocale(LC_CTYPE, "UTF8", "en_US.UTF-8");
+var_dump(escapeshellcmd('f{o}<€>'));
+var_dump(escapeshellarg('f~|;*Þ?'));
+var_dump(escapeshellcmd('?€®đæ?'));
+var_dump(escapeshellarg('aŊł€'));
+
+?>
+--EXPECT--
+string(13) "f\{o\}\<€\>"
+string(10) "'f~|;*Þ?'"
+string(13) "\?€®đæ\?"
+string(10) "'aŊł€'"
diff --git a/sapi/cli/tests/bug61546.phpt b/sapi/cli/tests/bug61546.phpt
new file mode 100644
index 0000000..071edb7
--- /dev/null
+++ b/sapi/cli/tests/bug61546.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #61546 (functions related to current script failed when chdir() in cli sapi)
+--FILE--
+<?php
+// reference doc for getmyinode() on php.net states that it returns an integer or FALSE on error
+// on Windows, getmyinode() returns 0 which normally casts to FALSE
+// however, the implementation of getmyinode() (in pageinfo.c) returns an explicit FALSE in the
+// event that the internal page_inode structure is less than 0, otherwise it returns the long value
+// of page_inode. therefore, an explicit 0 should be a passing value for this test.
+//
+// the ext/standard/tests/file/statpage.phpt test also tests getmyinode() returns an integer and will
+// pass even if that integer is 0. on Windows, the getmyinode() call in statpage.phpt returns 0 and
+// passes on Windows.
+$php = getenv("TEST_PHP_EXECUTABLE");
+$test_code = <<<PHP
+<?php
+chdir('..');
+var_dump(get_current_user() != "");
+chdir('..');
+var_dump(getmyinode() !== false);
+var_dump(getlastmod() != false);
+PHP;
+
+file_put_contents("bug61546_sub.php", $test_code);
+system($php . ' -n bug61546_sub.php');
+unlink("bug61546_sub.php");
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
diff --git a/sapi/cli/tests/bug61679.phpt b/sapi/cli/tests/bug61679.phpt
new file mode 100644
index 0000000..819ce2f
--- /dev/null
+++ b/sapi/cli/tests/bug61679.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #61679 (Error on non-standard HTTP methods)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+echo "This should never echo";
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+// Send a request with a fictitious request method,
+// I like smurfs, the smurf everything.
+if(fwrite($fp, <<<HEADER
+SMURF / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ // Only echo the first line from the response,
+ // the rest is not interesting
+ break;
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 501 Not Implemented
diff --git a/sapi/cli/tests/bug61977.phpt b/sapi/cli/tests/bug61977.phpt
new file mode 100644
index 0000000..09a6ba6
--- /dev/null
+++ b/sapi/cli/tests/bug61977.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Bug #61977 test CLI web-server support for Mime Type File extensions mapping
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('<?php ?>', true);
+
+/*
+ * If a Mime Type is added in php_cli_server.c, add it to this array and update
+ * the EXPECTF section accordingly
+ */
+$mimetypes = ['html', 'htm', 'svg', 'css', 'js', 'png', 'webm', 'ogv', 'ogg'];
+
+function test_mimetypes($mimetypes) {
+ foreach ($mimetypes as $mimetype) {
+ list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+ $port = intval($port) ? : 80;
+ $fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+ if (!$fp) die('Connect failed');
+ file_put_contents(__DIR__ . "/foo.{$mimetype}", '');
+ $header = <<<HEADER
+GET /foo.{$mimetype} HTTP/1.1
+Host: {$host}
+
+
+HEADER;
+ if (fwrite($fp, $header)) {
+ while (!feof($fp)) {
+ $text = fgets($fp);
+ if (strncasecmp("Content-type:", $text, 13) == 0) {
+ echo "foo.{$mimetype} => ", $text;
+ }
+ }
+ @unlink(__DIR__ . "/foo.{$mimetype}");
+ fclose($fp);
+ }
+ }
+}
+
+test_mimetypes($mimetypes);
+?>
+--EXPECTF--
+foo.html => Content-Type: text/html; charset=UTF-8
+foo.htm => Content-Type: text/html; charset=UTF-8
+foo.svg => Content-Type: image/svg+xml
+foo.css => Content-Type: text/css; charset=UTF-8
+foo.js => Content-Type: text/javascript; charset=UTF-8
+foo.png => Content-Type: image/png
+foo.webm => Content-Type: video/webm
+foo.ogv => Content-Type: video/ogg
+foo.ogg => Content-Type: audio/ogg
diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc
new file mode 100644
index 0000000..40c5361
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server.inc
@@ -0,0 +1,62 @@
+<?php
+define ("PHP_CLI_SERVER_HOSTNAME", "localhost");
+define ("PHP_CLI_SERVER_PORT", 8964);
+define ("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT);
+
+function php_cli_server_start($code = 'echo "Hello world";', $no_router = FALSE) {
+ $php_executable = getenv('TEST_PHP_EXECUTABLE');
+ $doc_root = __DIR__;
+ $router = "index.php";
+
+ if ($code) {
+ file_put_contents($doc_root . '/' . $router, '<?php ' . $code . ' ?>');
+ }
+
+ $descriptorspec = array(
+ 0 => STDIN,
+ 1 => STDOUT,
+ 2 => STDERR,
+ );
+
+ if (substr(PHP_OS, 0, 3) == 'WIN') {
+ $cmd = "{$php_executable} -t {$doc_root} -n -S " . PHP_CLI_SERVER_ADDRESS;
+ if (!$no_router) {
+ $cmd .= " {$router}";
+ }
+
+ $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true));
+ } else {
+ $cmd = "exec {$php_executable} -t {$doc_root} -n -S " . PHP_CLI_SERVER_ADDRESS;
+ if (!$no_router) {
+ $cmd .= " {$router}";
+ }
+ $cmd .= " 2>/dev/null";
+
+ $handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root);
+ }
+
+ // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.'
+ // it might not be listening yet...need to wait until fsockopen() call returns
+ $i = 0;
+ while (($i++ < 30) && !($fp = @fsockopen(PHP_CLI_SERVER_HOSTNAME, PHP_CLI_SERVER_PORT))) {
+ usleep(10000);
+ }
+
+ if ($fp) {
+ fclose($fp);
+ }
+
+ register_shutdown_function(
+ function($handle) use($router) {
+ proc_terminate($handle);
+ @unlink(__DIR__ . "/{$router}");
+ },
+ $handle
+ );
+ // don't bother sleeping, server is already up
+ // server can take a variable amount of time to be up, so just sleeping a guessed amount of time
+ // does not work. this is why tests sometimes pass and sometimes fail. to get a reliable pass
+ // sleeping doesn't work.
+}
+?>
+
diff --git a/sapi/cli/tests/php_cli_server_001.phpt b/sapi/cli/tests/php_cli_server_001.phpt
new file mode 100644
index 0000000..3f1083e
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_001.phpt
@@ -0,0 +1,16 @@
+--TEST--
+basic function
+--INI--
+allow_url_fopen=1
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start();
+var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS));
+?>
+--EXPECT--
+string(11) "Hello world"
diff --git a/sapi/cli/tests/php_cli_server_002.phpt b/sapi/cli/tests/php_cli_server_002.phpt
new file mode 100644
index 0000000..93151c1
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_002.phpt
@@ -0,0 +1,20 @@
+--TEST--
+$_SERVER variable
+--INI--
+allow_url_fopen=1
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_SERVER["DOCUMENT_ROOT"], $_SERVER["SERVER_SOFTWARE"], $_SERVER["SERVER_NAME"], $_SERVER["SERVER_PORT"]);');
+var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS));
+?>
+--EXPECTF--
+string(%d) "string(%d) "%stests"
+string(%d) "PHP %s Development Server"
+string(%d) "localhost"
+string(%d) "8964"
+"
diff --git a/sapi/cli/tests/php_cli_server_003.phpt b/sapi/cli/tests/php_cli_server_003.phpt
new file mode 100644
index 0000000..d1e95fe
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_003.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #55726 (Changing the working directory makes router script inaccessible)
+--INI--
+allow_url_fopen=1
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('chdir(__DIR__); echo "okey";');
+var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS));
+var_dump(file_get_contents("http://" . PHP_CLI_SERVER_ADDRESS));
+?>
+--EXPECTF--
+string(4) "okey"
+string(4) "okey"
diff --git a/sapi/cli/tests/php_cli_server_004.phpt b/sapi/cli/tests/php_cli_server_004.phpt
new file mode 100644
index 0000000..b61f886
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_004.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Bug #55747 (request headers missed in $_SERVER)
+--INI--
+allow_url_fopen=1
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('foreach($_SERVER as $k=>$v) { if (!strncmp($k, "HTTP", 4)) var_dump( $k . ":" . $v); }');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.1
+Host:{$host}
+User-Agent:dummy
+Custom:foo
+Referer:http://www.php.net/
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(19) "HTTP_HOST:localhost"
+string(21) "HTTP_USER_AGENT:dummy"
+string(15) "HTTP_CUSTOM:foo"
+string(32) "HTTP_REFERER:http://www.php.net/"
diff --git a/sapi/cli/tests/php_cli_server_005.phpt b/sapi/cli/tests/php_cli_server_005.phpt
new file mode 100644
index 0000000..ccc0f8f
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_005.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Post a file
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_FILES);');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+$post_data = <<<POST
+-----------------------------114782935826962
+Content-Disposition: form-data; name="userfile"; filename="laruence.txt"
+Content-Type: text/plain
+
+I am not sure about this.
+
+-----------------------------114782935826962--
+
+
+POST;
+
+$post_len = strlen($post_data);
+
+if(fwrite($fp, <<<HEADER
+POST / HTTP/1.1
+Host: {$host}
+Content-Type: multipart/form-data; boundary=---------------------------114782935826962
+Content-Length: {$post_len}
+
+
+{$post_data}
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+array(1) {
+ ["userfile"]=>
+ array(5) {
+ ["name"]=>
+ string(12) "laruence.txt"
+ ["type"]=>
+ string(10) "text/plain"
+ ["tmp_name"]=>
+ string(%d) "%s"
+ ["error"]=>
+ int(0)
+ ["size"]=>
+ int(26)
+ }
+}
diff --git a/sapi/cli/tests/php_cli_server_006.phpt b/sapi/cli/tests/php_cli_server_006.phpt
new file mode 100644
index 0000000..09e7ab0
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_006.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #55755 (SegFault when outputting header WWW-Authenticate)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.1
+Host: {$host}
+Authorization: Basic Zm9vOmJhcg==
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(3) "foo"
+string(3) "bar"
diff --git a/sapi/cli/tests/php_cli_server_007.phpt b/sapi/cli/tests/php_cli_server_007.phpt
new file mode 100644
index 0000000..64d4df0
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_007.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #55758 (Digest Authenticate missed in 5.4)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('header(\'WWW-Authenticate: Digest realm="foo",qop="auth",nonce="XXXXX",opaque="'.md5("foo").'"\');');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.1
+Host: {$host}
+Authorization: Basic Zm9vOmJhcg==
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+?>
+--EXPECTF--
+HTTP/1.1 401 Unauthorized
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+WWW-Authenticate: Digest realm="foo",qop="auth",nonce="XXXXX",opaque="acbd18db4cc2f85cedef654fccc4a4d8"
+Content-type: text/html
diff --git a/sapi/cli/tests/php_cli_server_008.phpt b/sapi/cli/tests/php_cli_server_008.phpt
new file mode 100644
index 0000000..2e68e24
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_008.phpt
@@ -0,0 +1,68 @@
+--TEST--
+SERVER_PROTOCOL header availability
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_SERVER["SERVER_PROTOCOL"]);');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.0
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(8) "HTTP/1.1"
+HTTP/1.0 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(8) "HTTP/1.0"
diff --git a/sapi/cli/tests/php_cli_server_009.phpt b/sapi/cli/tests/php_cli_server_009.phpt
new file mode 100644
index 0000000..2beaeed
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_009.phpt
@@ -0,0 +1,93 @@
+--TEST--
+PATH_INFO (relevant to #60112)
+--DESCRIPTION--
+After this fix(#60112), previously 404 request like "localhost/foo/bar"
+now could serve correctly with request_uri "index.php" and PATH_INFO "/foo/bar/"
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_SERVER["PATH_INFO"]);', TRUE);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET /foo/bar HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+
+if(fwrite($fp, <<<HEADER
+GET /foo/bar/ HTTP/1.0
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+
+if(fwrite($fp, <<<HEADER
+GET /foo/bar.js HTTP/1.0
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ break;
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(8) "/foo/bar"
+HTTP/1.0 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(9) "/foo/bar/"
+HTTP/1.0 404 Not Found
diff --git a/sapi/cli/tests/php_cli_server_010.phpt b/sapi/cli/tests/php_cli_server_010.phpt
new file mode 100644
index 0000000..2ef018b
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_010.phpt
@@ -0,0 +1,75 @@
+--TEST--
+Bug #60180 ($_SERVER["PHP_SELF"] incorrect)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('var_dump($_SERVER["PHP_SELF"], $_SERVER["SCRIPT_NAME"], $_SERVER["PATH_INFO"], $_SERVER["QUERY_STRING"]);', TRUE);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET /foo/bar?foo=bar HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+
+if(fwrite($fp, <<<HEADER
+GET /index.php/foo/bar/?foo=bar HTTP/1.0
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(18) "/index.php/foo/bar"
+string(10) "/index.php"
+string(8) "/foo/bar"
+string(7) "foo=bar"
+HTTP/1.0 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+string(19) "/index.php/foo/bar/"
+string(10) "/index.php"
+string(9) "/foo/bar/"
+string(7) "foo=bar"
diff --git a/sapi/cli/tests/php_cli_server_011.phpt b/sapi/cli/tests/php_cli_server_011.phpt
new file mode 100644
index 0000000..a957a8e
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_011.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Bug #60180 ($_SERVER["PHP_SELF"] incorrect)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('sytanx error;', TRUE);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+$logo_id = php_logo_guid();
+
+if(fwrite($fp, <<<HEADER
+GET /?={$logo_id} HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ if (("Content-Type: image/gif") == trim(fgets($fp))) {
+ echo "okey";
+ break;
+ }
+ }
+}
+
+fclose($fp);
+
+?>
+--EXPECTF--
+okey
diff --git a/sapi/cli/tests/php_cli_server_012.phpt b/sapi/cli/tests/php_cli_server_012.phpt
new file mode 100644
index 0000000..9a1e60c
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_012.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Bug #60159 (Router returns false, but POST is not passed to requested resource)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('print_r($_REQUEST); $_REQUEST["foo"] = "bar"; return FALSE;');
+$doc_root = __DIR__;
+file_put_contents($doc_root . '/request.php', '<?php print_r($_REQUEST); ?>');
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+POST /request.php HTTP/1.1
+Host: {$host}
+Content-Type: application/x-www-form-urlencoded
+Content-Length: 3
+
+a=b
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+@unlink($doc_root . '/request.php');
+
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+Array
+(
+ [a] => b
+)
+Array
+(
+ [a] => b
+ [foo] => bar
+)
diff --git a/sapi/cli/tests/php_cli_server_013.phpt b/sapi/cli/tests/php_cli_server_013.phpt
new file mode 100644
index 0000000..570798a
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_013.phpt
@@ -0,0 +1,108 @@
+--TEST--
+No router, no script
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(NULL, TRUE);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+$output = '';
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+
+if(fwrite($fp, <<<HEADER
+POST / HTTP/1.1
+Host: {$host}
+Content-Type: application/x-www-form-urlencoded
+Content-Length: 3
+
+a=b
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+
+echo preg_replace("/<style>(.*?)<\/style>/s", "<style>AAA</style>", $output), "\n";
+fclose($fp);
+
+
+$output = '';
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET /main/style.css HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+
+echo preg_replace("/<style>(.*?)<\/style>/s", "<style>AAA</style>", $output), "\n";
+fclose($fp);
+
+$output = '';
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+HEAD /main/foo/bar HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+
+echo preg_replace("/<style>(.*?)<\/style>/s", "<style>AAA</style>", $output), "\n";
+fclose($fp);
+?>
+--EXPECTF--
+
+HTTP/1.1 404 Not Found
+Host: %s
+Connection: close
+Content-Type: text/html; charset=UTF-8
+Content-Length: %d
+
+<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
+</head><body><h1>Not Found</h1><p>The requested resource / was not found on this server.</p></body></html>
+HTTP/1.1 404 Not Found
+Host: %s
+Connection: close
+Content-Type: text/html; charset=UTF-8
+Content-Length: %d
+
+<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
+</head><body><h1>Not Found</h1><p>The requested resource /main/style.css was not found on this server.</p></body></html>
+HTTP/1.1 404 Not Found
+Host: %s
+Connection: close
+Content-Type: text/html; charset=UTF-8
+Content-Length: %d
+
+<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
+</head><body><h1>Not Found</h1><p>The requested resource /main/foo/bar was not found on this server.</p></body></html>
+
diff --git a/sapi/cli/tests/php_cli_server_014.phpt b/sapi/cli/tests/php_cli_server_014.phpt
new file mode 100644
index 0000000..f8a9905
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_014.phpt
@@ -0,0 +1,80 @@
+--TEST--
+Bug #60477: Segfault after two multipart/form-data POST requestes
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('echo done, "\n";', TRUE);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+$output = '';
+
+// note: select() on Windows (& some other platforms) has historical issues with
+// timeouts less than 1000 millis(0.5). it may be better to increase these
+// timeouts to 1000 millis(1.0) (fsockopen eventually calls select()).
+// see articles like: http://support.microsoft.com/kb/257821
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+POST /index.php HTTP/1.1
+Host: {$host}
+Content-Type: multipart/form-data; boundary=---------123456789
+Content-Length: 70
+
+---------123456789
+Content-Type: application/x-www-form-urlencoded
+a=b
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+
+fclose($fp);
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if(fwrite($fp, <<<HEADER
+POST /main/no-exists.php HTTP/1.1
+Host: {$host}
+Content-Type: multipart/form-data; boundary=---------123456789
+Content-Length: 70
+
+---------123456789
+Content-Type: application/x-www-form-urlencoded
+a=b
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+
+echo preg_replace("/<style>(.*?)<\/style>/s", "<style>AAA</style>", $output), "\n";
+fclose($fp);
+
+?>
+--EXPECTF--
+
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: %s
+Content-type: %s
+
+done
+HTTP/1.1 404 Not Found
+Host: %s
+Connection: close
+Content-Type: %s
+Content-Length: %d
+
+<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
+</head><body><h1>Not Found</h1><p>The requested resource /main/no-exists.php was not found on this server.</p></body></html>
diff --git a/sapi/cli/tests/php_cli_server_015.phpt b/sapi/cli/tests/php_cli_server_015.phpt
new file mode 100644
index 0000000..6fb0169
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_015.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Bug #60523 (PHP Errors are not reported in browsers using built-in SAPI)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--INI--
+display_errors=1
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start('require("syntax_error.php");');
+$dir = realpath(dirname(__FILE__));
+
+file_put_contents($dir . "/syntax_error.php", "<?php non_exists_function(); ?>");
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+$output = '';
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET /index.php HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ $output .= fgets($fp);
+ }
+}
+echo $output;
+@unlink($dir . "/syntax_error.php");
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+<br />
+<b>Fatal error</b>: Call to undefined function non_exists_function() in <b>%ssyntax_error.php</b> on line <b>%s</b><br />
diff --git a/sapi/cli/tests/php_cli_server_016.phpt b/sapi/cli/tests/php_cli_server_016.phpt
new file mode 100644
index 0000000..f15aff1
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_016.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Bug #60591 (Memory leak when access a non-exists file)
+--DESCRIPTION--
+this is an indirect test for bug 60591, since mem leak is reproted in the server side
+and require php compiled with --enable-debug
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"]))
+ return false; // serve the requested resource as-is.
+else {
+ echo "here";
+}
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+POST /no-exists.jpg HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ break;
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 404 Not Found
diff --git a/sapi/cli/tests/php_cli_server_017.phpt b/sapi/cli/tests/php_cli_server_017.phpt
new file mode 100644
index 0000000..73530af
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_017.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Implement Req #60850 (Built in web server does not set $_SERVER['SCRIPT_FILENAME'] when using router)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+var_dump($_SERVER['SCRIPT_FILENAME']);
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+POST / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+string(%d) "%sindex.php"
diff --git a/sapi/cli/tests/php_cli_server_018.phpt b/sapi/cli/tests/php_cli_server_018.phpt
new file mode 100644
index 0000000..deb9348
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_018.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Implement Req #61679 (Support HTTP PATCH method)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+var_dump($_SERVER['REQUEST_METHOD']);
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+PATCH / HTTP/1.1
+Host: {$host}
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: %s
+Content-type: text/html
+
+string(5) "PATCH"
diff --git a/sapi/cli/tests/skipif.inc b/sapi/cli/tests/skipif.inc
new file mode 100644
index 0000000..79e6c91
--- /dev/null
+++ b/sapi/cli/tests/skipif.inc
@@ -0,0 +1,7 @@
+<?php
+
+if (php_sapi_name() != "cli") {
+ die("skip CLI only");
+}
+
+?>