From 5f88d1862026a3cc7b42d61b26f915da5122e398 Mon Sep 17 00:00:00 2001 From: Martin Sikora Date: Fri, 18 Aug 2017 20:28:56 +0200 Subject: [PATCH 1/4] added new command to parse a single file --- doc-parser.php | 2 ++ src/Command/ParserCommand.php | 21 +++++++++++ src/Command/RunCommand.php | 18 ++-------- src/Command/SingleCommand.php | 67 +++++++++++++++++++++++++++++++++++ src/Parser.php | 8 ++--- 5 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 src/Command/ParserCommand.php create mode 100644 src/Command/SingleCommand.php diff --git a/doc-parser.php b/doc-parser.php index c41055c..a67685d 100644 --- a/doc-parser.php +++ b/doc-parser.php @@ -29,8 +29,10 @@ // Setup cli commands $runCmd = new \DocParser\Command\RunCommand(); +$singleCmd = new \DocParser\Command\SingleCommand(); $application = new \Symfony\Component\Console\Application(); $application->add($runCmd); +$application->add($singleCmd); $application->setDefaultCommand($runCmd->getName()); $application->run(); \ No newline at end of file diff --git a/src/Command/ParserCommand.php b/src/Command/ParserCommand.php new file mode 100644 index 0000000..75562a2 --- /dev/null +++ b/src/Command/ParserCommand.php @@ -0,0 +1,21 @@ +addOption('examples', 'e', InputOption::VALUE_REQUIRED, 's = skip, i = include, e = export') ->addOption('out-dir', 'o', InputOption::VALUE_REQUIRED, 'Output directory for parsed JSON manual', './output') ->addOption('tmp-dir', 't', InputOption::VALUE_REQUIRED, 'Directory for temporary files', sys_get_temp_dir()) - ->addOption('pretty', null, InputOption::VALUE_NONE, 'Pretty print JSON output') + ->addOption('pretty', 'p', InputOption::VALUE_NONE, 'Pretty print JSON output') ; } @@ -103,7 +102,6 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->downloadPackage($package); $this->unpackPackage($package); -// $results = $this->process($unpackedDir, $includeExamples); $this->parse($package, $outDir, $includeExamples); $package->cleanup(); @@ -117,7 +115,6 @@ private function chooseLanguages() { $question = new ChoiceQuestion($msg, $choices, $default); $question->setAutocompleterValues(null); -// $languages = $this->languages; $question->setValidator(function($selected) use ($choices) { $selected = array_map(function($val) { return trim($val); @@ -155,16 +152,6 @@ private function chooseIncludeExamples() { return $this->helper->ask($this->input, $this->output, $question); } - private function stringExamplesParamsToConst($include) { - if ($include == 'i') { - return Parser::INCLUDE_EXAMPLES; - } elseif ($include == 'e') { - return Parser::EXPORT_EXAMPLES; - } else { - return Parser::SKIP_EXAMPLES; - } - } - private function downloadPackage(Package $package) { $url = $package->getUrl(); @@ -258,7 +245,6 @@ private function parse(Package $package, $outDir, $includeExamples) { $this->output->writeln("Skipped ${filename}"); } } -// $this->output->writeln("Total: ${count} examples"); } private function saveOutput($basePath, $functions) { diff --git a/src/Command/SingleCommand.php b/src/Command/SingleCommand.php new file mode 100644 index 0000000..2ce57aa --- /dev/null +++ b/src/Command/SingleCommand.php @@ -0,0 +1,67 @@ +setName('parser:single') + ->setDescription('Parse a single HTML file') + ->addArgument('file', InputArgument::REQUIRED, 'Path to the file you want to process') + ->addOption('examples', 'e', InputOption::VALUE_NONE, 'Include examples') + ->addOption('output', 'o', InputOption::VALUE_OPTIONAL, 'Write the output to a file') + ->addOption('pretty', 'p', InputOption::VALUE_NONE, 'Pretty print JSON output') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $file = $input->getArgument('file'); + $parseExamples = boolval($input->getOption('examples')) ? Parser::INCLUDE_EXAMPLES : 0; + + $outputFile = $input->getOption('output'); + $pretty = boolval($input->getOption('pretty')); + + if (!file_exists($file) || !is_readable($file)) { + $output->writeln("File \"${file}\" doesn't exist or is not readable."); + return 1; + } + + $parser = new Parser(); + $parserResult = $parser->processFile($file, $parseExamples); + + $funcName = $parserResult->getFuncNames()[0]; + $result = $parserResult->getResult($funcName); + + if ($parseExamples === Parser::INCLUDE_EXAMPLES) { + $result['examples'] = $parserResult->getExamples($funcName); + } + + $jsonData = json_encode($result, $pretty ? JSON_PRETTY_PRINT : 0); + + if ($outputFile) { + file_put_contents($outputFile, $jsonData); + } else { + $output->write($jsonData); + } + } + +} diff --git a/src/Parser.php b/src/Parser.php index 9a97fae..e043d06 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -26,7 +26,7 @@ class Parser { /** * Process all files in the directory with selected by getFilesToProcess() method. * - * @param $dir Directory to search for files + * @param string $dir Directory to search for files * @param int $parseExamples Whether or not include also examples * @param callable $progressCallback Optional callback used to monitor progress * @return ParserResult Parse result including all warnings and skipped files @@ -46,7 +46,7 @@ public function processDir($dir, $parseExamples = 0, \Closure $progressCallback } /** - * @param $dir Directory where we want to search files + * @param string $dir Directory where we want to search files * @return array */ public function getFilesToProcess($dir) { @@ -56,8 +56,8 @@ public function getFilesToProcess($dir) { /** * Process single file. * - * @param $file Source file - * @param $parseExamples Whether or not include also examples + * @param string $file Source file + * @param number $parseExamples Whether or not include also examples * @return ParserResult Parse result including all warnings and skipped files */ public function processFile($file, $parseExamples, $result = null) { From 969902197759baa85f839fc694690eb5588f993d Mon Sep 17 00:00:00 2001 From: Martin Sikora Date: Sun, 20 Aug 2017 16:49:10 +0200 Subject: [PATCH 2/4] rewrite some tests to PHPUnit, fix cases like "strtr" function --- composer.json | 9 +- features/availability.feature | 12 - features/bootstrap/AvailabilityContext.php | 42 -- features/bootstrap/PackageContext.php | 70 ---- features/bootstrap/ParserContext.php | 106 ----- features/bootstrap/UtilsContext.php | 42 -- features/package.feature | 19 - features/parser.feature | 20 - features/utils.feature | 11 - src/Availability.php | 22 +- src/Command/ParserCommand.php | 21 - src/Command/RunCommand.php | 81 +++- src/Command/SingleCommand.php | 7 +- src/Package.php | 63 ++- src/Parser.php | 47 +-- src/Utils.php | 44 +- tests/AvailabilityTest.php | 23 ++ tests/PackageTest.php | 46 +++ tests/ParserTest.php | 42 ++ tests/test-manual-files/datetime.setdate.html | 192 +++++++++ tests/test-manual-files/datetime.setdate.json | 79 ++++ .../eventhttp.setcallback.html | 194 +++++++++ .../eventhttp.setcallback.json | 43 ++ .../function.array-diff.html | 159 +++++++ .../function.array-diff.json | 45 ++ tests/test-manual-files/function.chown.html | 139 +++++++ tests/test-manual-files/function.chown.json | 37 ++ .../function.json-encode.html | 391 ++++++++++++++++++ .../function.json-encode.json | 65 +++ .../function.str-replace.html | 201 +++++++++ .../function.str-replace.json | 57 +++ tests/test-manual-files/function.strrpos.html | 189 +++++++++ tests/test-manual-files/function.strrpos.json | 53 +++ tests/test-manual-files/function.strtr.html | 220 ++++++++++ tests/test-manual-files/function.strtr.json | 72 ++++ .../reflectionclass.getname.html | 98 +++++ .../reflectionclass.getname.json | 24 ++ .../splfileobject.fgetcsv.html | 165 ++++++++ .../splfileobject.fgetcsv.json | 51 +++ 39 files changed, 2737 insertions(+), 464 deletions(-) delete mode 100644 features/availability.feature delete mode 100644 features/bootstrap/AvailabilityContext.php delete mode 100644 features/bootstrap/PackageContext.php delete mode 100644 features/bootstrap/ParserContext.php delete mode 100644 features/bootstrap/UtilsContext.php delete mode 100644 features/package.feature delete mode 100644 features/parser.feature delete mode 100644 features/utils.feature delete mode 100644 src/Command/ParserCommand.php create mode 100644 tests/AvailabilityTest.php create mode 100644 tests/PackageTest.php create mode 100644 tests/ParserTest.php create mode 100644 tests/test-manual-files/datetime.setdate.html create mode 100644 tests/test-manual-files/datetime.setdate.json create mode 100644 tests/test-manual-files/eventhttp.setcallback.html create mode 100644 tests/test-manual-files/eventhttp.setcallback.json create mode 100644 tests/test-manual-files/function.array-diff.html create mode 100644 tests/test-manual-files/function.array-diff.json create mode 100644 tests/test-manual-files/function.chown.html create mode 100644 tests/test-manual-files/function.chown.json create mode 100644 tests/test-manual-files/function.json-encode.html create mode 100644 tests/test-manual-files/function.json-encode.json create mode 100644 tests/test-manual-files/function.str-replace.html create mode 100644 tests/test-manual-files/function.str-replace.json create mode 100644 tests/test-manual-files/function.strrpos.html create mode 100644 tests/test-manual-files/function.strrpos.json create mode 100644 tests/test-manual-files/function.strtr.html create mode 100644 tests/test-manual-files/function.strtr.json create mode 100644 tests/test-manual-files/reflectionclass.getname.html create mode 100644 tests/test-manual-files/reflectionclass.getname.json create mode 100644 tests/test-manual-files/splfileobject.fgetcsv.html create mode 100644 tests/test-manual-files/splfileobject.fgetcsv.json diff --git a/composer.json b/composer.json index 22da7f6..100bf84 100644 --- a/composer.json +++ b/composer.json @@ -10,18 +10,15 @@ "ext-curl": "*" }, "require-dev": { - "behat/behat": "2.4.*@stable", - "phpunit/phpunit": "4.6.*" + "phpunit/phpunit": "~6.3" }, "bin": [ "doc-parser" ], - "config": { - "bin-dir": "bin/" - }, "autoload": { "psr-4": { - "DocParser\\": ["src/"] + "DocParser\\": ["src/"], + "DocParser\\Tests\\": ["tests/"] } }, "autoload-dev": { diff --git a/features/availability.feature b/features/availability.feature deleted file mode 100644 index 29c7438..0000000 --- a/features/availability.feature +++ /dev/null @@ -1,12 +0,0 @@ -Feature: availability - In order to choose which languages for PHP manual - As a parser script - I want to download php.net/download-docs.php and list available languages - - Scenario: Run the CLI tool parser.php which lets you choose the languages you want - When I want a list all available languages - Then I should get these and more: - | lang | title | - | en | English | - | es | Spanish | - | de | German | \ No newline at end of file diff --git a/features/bootstrap/AvailabilityContext.php b/features/bootstrap/AvailabilityContext.php deleted file mode 100644 index b815b13..0000000 --- a/features/bootstrap/AvailabilityContext.php +++ /dev/null @@ -1,42 +0,0 @@ -languages = $avail->listPackages(); - } - - /** - * @Then /^I should get these and more:$/ - */ - public function iShouldGetTheseAndMore(TableNode $table) - { - foreach ($table->getHash() as $row) { - assertArrayHasKey($row['lang'], $this->languages, 'Language ' . $row['lang'] . ' must be among available languages.'); - assertEquals($row['title'], $this->languages[$row['lang']]); - } - foreach ($this->languages as $code => $title) { - assertNotEmpty($title); - } - assertGreaterThan(10, count($this->languages), 'There are missing languages for sure!'); - } - -} diff --git a/features/bootstrap/PackageContext.php b/features/bootstrap/PackageContext.php deleted file mode 100644 index ce3d554..0000000 --- a/features/bootstrap/PackageContext.php +++ /dev/null @@ -1,70 +0,0 @@ -package = new Package($lang, $mirror); - } - - /** - * @Then /^The package can be downloaded to system\'s tmp dir$/ - */ - public function thePackageCanBeDownloadedToSystemSTmpDir() - { - $this->dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php-doc-parser-test'; - @mkdir($this->dir); - - $file = $this->dir . DIRECTORY_SEPARATOR . $this->package->getOrigFilename(); - - $this->package->download($file); - } - - /** - * @Given /^Unpack files to the same directory:$/ - */ - public function unpackFilesToTheSameDirectory(PyStringNode $string) - { - $expectedFiles = $string->getLines(); - $this->pagesDir = $this->package->unpack($expectedFiles); - assertFileExists($this->pagesDir); - - chdir($this->pagesDir); - $foundFiles = array_flip(glob('*.html')); - assertCount(count($expectedFiles), $foundFiles); - - foreach ($expectedFiles as $file) { - assertArrayHasKey($file, $foundFiles); - } - } - - /** - * @Given /^Cleanup files when it\'s all done$/ - */ - public function cleanupFilesWhenItSAllDone() - { - $this->package->cleanup(); - assertFileNotExists($this->pagesDir, 'Directory "' . $this->pagesDir . '" wasn\'t removed.'); - } - -} diff --git a/features/bootstrap/ParserContext.php b/features/bootstrap/ParserContext.php deleted file mode 100644 index 3a3e47f..0000000 --- a/features/bootstrap/ParserContext.php +++ /dev/null @@ -1,106 +0,0 @@ -parser = new Parser(); -// var_dump($this->testFilesDir);exit; - } - - /** - * @Given /^these test files:$/ - */ - public function theseTestFiles(TableNode $table) - { - $this->testFiles = $table->getHash(); - } - - /** - * @Then /^match them with files from "([^"]*)"$/ - */ - public function matchThemWithFilesFrom($dir) - { - $this->testFilesDir = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..') . DIRECTORY_SEPARATOR . $dir; - - foreach ($this->testFiles as $row) { - $expected = json_decode(file_get_contents($this->testFilesDir . DIRECTORY_SEPARATOR . $row['expected-json-result']), true); - - $result = $this->parser->processFile($this->testFilesDir . DIRECTORY_SEPARATOR . $row['source-filename'], Parser::INCLUDE_EXAMPLES); - $funcName = $result->getFuncNames()[0]; - - $actual = array_merge($result->getResult($funcName), [ - 'examples' => $result->getExamples($funcName) - ]); - -// echo json_encode($actual, JSON_PRETTY_PRINT); - - assertEquals($expected, $actual); - } - } - - /** - * @Then /^download manual from "([^"]*)" package from "([^"]*)"$/ - */ - public function downloadManualFromPackageFrom($lang, $mirror) - { - $this->package = new Package($lang, $mirror); - - $dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php-doc-parser-test'; - @mkdir($dir); - $file = $dir . DIRECTORY_SEPARATOR . $this->package->getOrigFilename(); - - $this->package->download($file); - $testUnpackDir = $this->package->unpack(array_map(function($item) { return $item['source-filename']; }, $this->testFiles)); - - $this->unpackedFilesDir = $this->package->getUnpackedDir(); - - assertEquals($testUnpackDir, $this->unpackedFilesDir); - assertCount(count($this->testFiles), glob($this->unpackedFilesDir . DIRECTORY_SEPARATOR . '*.html')); - } - - /** - * @Given /^test downloaded files against them as well$/ - */ - public function testDownloadedFilesAgainstThemAsWell() - { -// $files = glob($this->downloadedFilesDir . DIRECTORY_SEPARATOR . '*.html'); - - foreach ($this->testFiles as $row) { - $file = $row['source-filename']; - $expectedFileSize = filesize($this->unpackedFilesDir . DIRECTORY_SEPARATOR . $file); - $testFileSize = filesize($this->testFilesDir . DIRECTORY_SEPARATOR . $file); - - if ($expectedFileSize != $testFileSize) { - echo "File sizes doesn't match for \"${file}\"! Documentation might not match the tested sample.\n"; - } - -// $actual = $this->parser->processFile($this->testFilesDir . DIRECTORY_SEPARATOR . $file); - } - - $this->package->cleanup(); - } -} \ No newline at end of file diff --git a/features/bootstrap/UtilsContext.php b/features/bootstrap/UtilsContext.php deleted file mode 100644 index 0aa18f7..0000000 --- a/features/bootstrap/UtilsContext.php +++ /dev/null @@ -1,42 +0,0 @@ -testArrays = $table->getHash(); - } - - /** - * @Then /^I need to convert it recursively to a low level more efficient SplFixedArray$/ - */ - public function iNeedToConvertItRecursivelyToALowLevelMoreEfficientSplfixedarray() - { - /** - * Probably not very helpful - */ - foreach ($this->testArrays as $json) { - $array = json_decode($json['test-array-as-json'], true); -// $fixed = Utils::toFixedArray($array); -// var_dump(memory_get_peak_usage(true) / 1000000); - } - - } - -} \ No newline at end of file diff --git a/features/package.feature b/features/package.feature deleted file mode 100644 index 4ce8fa9..0000000 --- a/features/package.feature +++ /dev/null @@ -1,19 +0,0 @@ -Feature: package - In order to parse the documentation - As a parser script - I need to download and unpack the manual to a temporary directory - - Scenario: - When I need "fr" manual from "cz1.php.net" - Then The package can be downloaded to system's tmp dir - And Unpack files to the same directory: - """ - class.pdo.html - class.splheap.html - datetime.diff.html - function.cos.html - function.is-string.html - function.print-r.html - function.strcmp.html - """ - Then Cleanup files when it's all done \ No newline at end of file diff --git a/features/parser.feature b/features/parser.feature deleted file mode 100644 index 9f797bb..0000000 --- a/features/parser.feature +++ /dev/null @@ -1,20 +0,0 @@ -Feature: Parser - In order to get a manual page in JSON format - As a developer - I need to run series of XPath queries that process the HTML page - - Scenario: - Given these test files: - | source-filename | expected-json-result | - | datetime.setdate.html | datetime.setdate.json | - | eventhttp.setcallback.html | eventhttp.setcallback.json | - | function.array-diff.html | function.array-diff.json | - | function.chown.html | function.chown.json | - | function.json-encode.html | function.json-encode.json | - | function.str-replace.html | function.str-replace.json | - | function.strrpos.html | function.strrpos.json | - | reflectionclass.getname.html | reflectionclass.getname.json | - | splfileobject.fgetcsv.html | splfileobject.fgetcsv.json | - Then match them with files from "test-manual-files" - Then download manual from "en" package from "cz1.php.net" - And test downloaded files against them as well diff --git a/features/utils.feature b/features/utils.feature deleted file mode 100644 index a82bec2..0000000 --- a/features/utils.feature +++ /dev/null @@ -1,11 +0,0 @@ -Feature: Utils - In order to do some common things when parsing manual pages - As a developer - I need to have a set of static methods that can be used independently - - Scenario: - When I have a very large multi-dimensional array: - | test-array-as-json | - | [ "a", "b", ["c", ["d"]], "e"] | - | { "k1": "a", "k2": { "k3": [ 1, 2, 3 ] }, "k4": [ 4, 5 ] } | - Then I need to convert it recursively to a low level more efficient SplFixedArray \ No newline at end of file diff --git a/src/Availability.php b/src/Availability.php index 2eecdd5..e4dd3dd 100644 --- a/src/Availability.php +++ b/src/Availability.php @@ -16,14 +16,7 @@ class Availability { * @throws \Exception */ public function listPackages() { - $curl = curl_init(self::DOWNLOADS_URL); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - $response = curl_exec($curl); - - $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - if (200 != $statusCode) { - throw new \Exception("Invalid status lang ${statusCode} for page " . self::DOWNLOADS_URL); - } + $response = $this->download(); $dom = new \DOMDocument(); @$dom->loadHTML($response); @@ -62,4 +55,17 @@ public function listPackages() { return $langs; } + private function download() { + $curl = curl_init(self::DOWNLOADS_URL); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($curl); + + $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + if (200 != $statusCode) { + throw new \Exception("Invalid status lang ${statusCode} for page " . self::DOWNLOADS_URL); + } + + return $response; + } + } \ No newline at end of file diff --git a/src/Command/ParserCommand.php b/src/Command/ParserCommand.php deleted file mode 100644 index 75562a2..0000000 --- a/src/Command/ParserCommand.php +++ /dev/null @@ -1,21 +0,0 @@ -setName('parser:run') ->setDescription('Run interactive parser console') @@ -56,7 +73,8 @@ protected function configure() { ; } - protected function execute(InputInterface $input, OutputInterface $output) { + protected function execute(InputInterface $input, OutputInterface $output) + { $this->avail = new Availability(); $this->output = $output; $this->input = $input; @@ -108,7 +126,8 @@ protected function execute(InputInterface $input, OutputInterface $output) { } } - private function chooseLanguages() { + private function chooseLanguages() + { $default = 'en'; $choices = array_merge(['all' => 'All'], $this->allLanguages); $msg = "Choose languages you want to download.\nUse comma to separate multiple languages (default: ${default}):"; @@ -130,13 +149,15 @@ private function chooseLanguages() { return $this->helper->ask($this->input, $this->output, $question); } - private function chooseMirror() { + private function chooseMirror() + { $default = 'php.net'; $question = new Question("Choose mirror site (default: ${default}): ", $default); return $this->helper->ask($this->input, $this->output, $question); } - private function chooseIncludeExamples() { + private function chooseIncludeExamples() + { $default = 'i'; $choices = [ 'i' => 'Include examples', @@ -152,7 +173,8 @@ private function chooseIncludeExamples() { return $this->helper->ask($this->input, $this->output, $question); } - private function downloadPackage(Package $package) { + private function downloadPackage(Package $package) + { $url = $package->getUrl(); preg_match('/\/(php_manual.*)\//U', $url, $matches); @@ -177,14 +199,16 @@ private function downloadPackage(Package $package) { } } - public function unpackPackage(Package $package) { + public function unpackPackage(Package $package) + { $this->output->writeln('Unpacking ' . $package->getOrigFilename() . ' ...'); $manualDir = $package->unpack(); $this->output->writeln('Unpacked to ' . $manualDir . "\n"); return $manualDir; } - private function parse(Package $package, $outDir, $includeExamples) { + private function parse(Package $package, $outDir, $includeExamples = false) + { $parser = new Parser(); $bar = $this->createProgressBar(count($parser->getFilesToProcess($package->getUnpackedDir()))); @@ -206,11 +230,11 @@ private function parse(Package $package, $outDir, $includeExamples) { $examplesRes = $results->getExamples($funcName); if ($examplesRes && is_array($arrayRes)) { - if ($includeExamples == Parser::INCLUDE_EXAMPLES) { + if ($includeExamples == RunCommand::INCLUDE_EXAMPLES) { $arrayRes = array_merge($arrayRes, [ 'examples' => $examplesRes ]); - } elseif ($includeExamples == Parser::EXPORT_EXAMPLES) { + } elseif ($includeExamples == RunCommand::EXPORT_EXAMPLES) { $examples[$funcName] = $examplesRes; } } @@ -227,7 +251,7 @@ private function parse(Package $package, $outDir, $includeExamples) { $this->saveFunctionsList($basePath, $functions); - if ($includeExamples == Parser::EXPORT_EXAMPLES) { + if ($includeExamples == RunCommand::EXPORT_EXAMPLES) { $this->saveExamples($basePath, $examples); $this->output->writeln("Total examples: " . $results->countAllExamples() . ""); } @@ -247,7 +271,8 @@ private function parse(Package $package, $outDir, $includeExamples) { } } - private function saveOutput($basePath, $functions) { + private function saveOutput($basePath, $functions) + { $json = json_encode($functions, $this->getJsonEncoderFlags()); $filePath = $basePath . '.json'; file_put_contents($filePath, $json); @@ -256,7 +281,8 @@ private function saveOutput($basePath, $functions) { $this->printJsonError(); } - private function saveExamples($basePath, $examples) { + private function saveExamples($basePath, $examples) + { $json = json_encode($examples, $this->getJsonEncoderFlags()); $filePath = $basePath . '.examples.json'; file_put_contents($filePath, $json); @@ -265,7 +291,8 @@ private function saveExamples($basePath, $examples) { $this->printJsonError(); } - private function saveFunctionsList($basePath, $functions) { + private function saveFunctionsList($basePath, $functions) + { $normalized = array_map(function($name) { return strtolower($name); }, array_keys($functions)); @@ -277,17 +304,20 @@ private function saveFunctionsList($basePath, $functions) { $this->printJsonError(); } - private function getTmpDir() { + private function getTmpDir() + { return ($this->input->getOption('tmp-dir') ?: sys_get_temp_dir()); } - private function printJsonError() { + private function printJsonError() + { if (json_last_error()) { $this->output->writeln('' . json_last_error_msg() . ''); } } - private function checkMemoryLimit() { + private function checkMemoryLimit() + { $memLimit = ini_get('memory_limit'); $minimumRequired = 128; $bytes = Utils::convertSize(ini_get('memory_limit')); @@ -297,7 +327,8 @@ private function checkMemoryLimit() { } } - private function createProgressBar($max = 100) { + private function createProgressBar($max = 100) + { $bar = new ProgressBar($this->output, $max); $bar->setBarCharacter('#'); $bar->setProgressCharacter('#'); @@ -305,8 +336,18 @@ private function createProgressBar($max = 100) { return $bar; } - private function getJsonEncoderFlags() { + private function getJsonEncoderFlags() + { return ($this->input->getOption('pretty') ? JSON_PRETTY_PRINT : 0) | JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE; } + private function stringExamplesParamsToConst($include) { + if ($include == 'i') { + return self::INCLUDE_EXAMPLES; + } elseif ($include == 'e') { + return self::EXPORT_EXAMPLES; + } else { + return self::SKIP_EXAMPLES; + } + } } \ No newline at end of file diff --git a/src/Command/SingleCommand.php b/src/Command/SingleCommand.php index 2ce57aa..d628aa5 100644 --- a/src/Command/SingleCommand.php +++ b/src/Command/SingleCommand.php @@ -7,8 +7,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Command\Command; -class SingleCommand extends ParserCommand { +class SingleCommand extends Command { /** * @var InputInterface; @@ -35,7 +36,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $file = $input->getArgument('file'); - $parseExamples = boolval($input->getOption('examples')) ? Parser::INCLUDE_EXAMPLES : 0; + $parseExamples = boolval($input->getOption('examples')); $outputFile = $input->getOption('output'); $pretty = boolval($input->getOption('pretty')); @@ -51,7 +52,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $funcName = $parserResult->getFuncNames()[0]; $result = $parserResult->getResult($funcName); - if ($parseExamples === Parser::INCLUDE_EXAMPLES) { + if ($parseExamples) { $result['examples'] = $parserResult->getExamples($funcName); } diff --git a/src/Package.php b/src/Package.php index e874eeb..279ec35 100644 --- a/src/Package.php +++ b/src/Package.php @@ -15,20 +15,26 @@ class Package { const ARCHIVE_INNER_DIR = 'php-chunked-xhtml'; - public function __construct($lang, $mirror) { + public function __construct($lang, $mirror) + { $this->lang = $lang; $this->mirror = $mirror; } - public function download($filePath, $progressCallback = null) { - $this->filePath = $filePath; + public function download($filePath = null, $progressCallback = null) + { + if (!$filePath) { + $tmpDir = $this->getTmpDir(); + $filePath = $tmpDir . DIRECTORY_SEPARATOR . $this->getOrigFilename(); + @mkdir($tmpDir); + } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->getUrl()); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - $f = fopen($this->filePath, 'w+'); + $f = fopen($filePath, 'w+'); curl_setopt($ch, CURLOPT_FILE, $f); if ($progressCallback) { curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $progressCallback); @@ -39,13 +45,17 @@ public function download($filePath, $progressCallback = null) { fclose($f); - $this->isPackageFileValid(); + $this->isPackageFileValid($filePath); + $this->filePath = $filePath; $this->cleanupFiles[] = $this->filePath; + + return $filePath; } - public function unpack($files = []) { - $this->isPackageFileValid(); + public function unpack($files = []) + { + $this->isPackageFileValid($this->filePath); // decompress from gz $tarFile = str_replace('.tar.gz', '.tar', $this->filePath); @@ -65,44 +75,57 @@ public function unpack($files = []) { return $this->unpackedDir; } - public function cleanup() { + public function cleanup() + { $fs = new Filesystem(); try { $fs->remove($this->cleanupFiles); - } catch (IOExceptionInterface $e) { - new IOException("Unable to remove files/directories: " . implode(', ', $this->cleanupFiles)); + } catch (IOException $e) { + throw new IOException("Unable to remove files/directories: " . implode(', ', $this->cleanupFiles)); } } - private function isPackageFileValid() { - if (!file_exists($this->filePath)) { - throw new \Exception('File "' . $this->filePath . '" doesn\'t exist. Did you call Package::download() before Package::unpack()?'); + private function isPackageFileValid($filePath) + { + if (!file_exists($filePath)) { + throw new \Exception('File "' . $filePath . '" doesn\'t exist. Did you call Package::download() before Package::unpack()?'); } - if (0 == filesize($this->filePath)) { - throw new \Exception('File "' . $this->filePath . '" has 0 length. You might have a wrong mirror site or language file. ' . + if (0 == filesize($filePath)) { + throw new \Exception('File "' . $filePath . '" has 0 length. You might have a wrong mirror site or language file. ' . 'Try opening this this URL in a browser: ' . $this->getUrl()); } } - public function getUrl() { + private function getTmpDir() + { + $dir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php-doc-parser-test'; + return $dir; + } + + public function getUrl() + { return 'http://' . $this->mirror . '/get/' . $this->getOrigFilename() . '/from/this/mirror'; } - public function getOrigFilename() { + public function getOrigFilename() + { return 'php_manual_' . $this->lang . '.tar.gz'; } - public function getLang() { + public function getLang() + { return $this->lang; } - public function getMirror() { + public function getMirror() + { return $this->mirror; } - public function getUnpackedDir() { + public function getUnpackedDir() + { return $this->unpackedDir; } } \ No newline at end of file diff --git a/src/Parser.php b/src/Parser.php index e043d06..495b81d 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -6,32 +6,15 @@ use DocParser\Utils; class Parser { - - /** - * Don't parser examples at all - */ - const SKIP_EXAMPLES = 0; - - /** - * Parse examples and include them in function definitions - */ - const INCLUDE_EXAMPLES = 1; - - /** - * Parse examples but keep them in separate arrays - */ - const EXPORT_EXAMPLES = 2; - - /** * Process all files in the directory with selected by getFilesToProcess() method. * * @param string $dir Directory to search for files - * @param int $parseExamples Whether or not include also examples + * @param boolean $parseExamples Whether or not include also examples * @param callable $progressCallback Optional callback used to monitor progress * @return ParserResult Parse result including all warnings and skipped files */ - public function processDir($dir, $parseExamples = 0, \Closure $progressCallback = null) { + public function processDir($dir, $parseExamples = true, \Closure $progressCallback = null) { $results = new ParserResult(); $files = $this->getFilesToProcess($dir); $processed = 0; @@ -57,14 +40,18 @@ public function getFilesToProcess($dir) { * Process single file. * * @param string $file Source file - * @param number $parseExamples Whether or not include also examples + * @param boolean $parseExamples Whether or not include also examples * @return ParserResult Parse result including all warnings and skipped files */ - public function processFile($file, $parseExamples, $result = null) { + public function processFile($file, $parseExamples = true, $result = null) { if (!$result) { $result = new ParserResult(); } + if (!file_exists($file)) { + throw new \Exception("File \"${file}\" doesn't exist."); + } + $dom = new \DOMDocument(); @$dom->loadHTML(file_get_contents($file)); // Most important object used to traverse HTML DOM structure. @@ -162,9 +149,9 @@ public function processFile($file, $parseExamples, $result = null) { $paramDescriptions = null; $varName = $paramNodes->item(1)->textContent; - foreach ($allParameters as $index => $paramDesc) { + foreach ($allParameters as $j => $paramDesc) { if (ltrim($varName, '$&') == $paramDesc->textContent) { - $paramDescriptions = $xpath->query('//div[contains(@class,"parameters")]/dl/dd[' . ($index + 1) . ']'); + $paramDescriptions = $xpath->query('//div[contains(@class,"parameters")]/dl/dd[' . ($j + 1) . ']'); break; } } @@ -193,16 +180,21 @@ public function processFile($file, $parseExamples, $result = null) { return $result; } - $funcName = strtolower($function['params'][0]['name']); + // Find all possible names for this function + $names = []; foreach ($function['params'] as $index => $param) { - // Use all alternative names just as a reference to the first (primary) name. - $name = strtolower($function['params'][$index]['name']); + $names[] = strtolower($function['params'][$index]['name']); + } + $funcName = $names[0]; + + // Use all alternative names just as a reference to the first (primary) name. + foreach (array_unique($names) as $index => $name) { $result->setResult($name, $index == 0 ? $function : $funcName); } // Parse all examples in this file. - if ($parseExamples != self::SKIP_EXAMPLES) { + if ($parseExamples) { // Find all source code containers. $exampleDiv = $xpath->query('//div[@class="example" or @class="informalexample"]'); for ($i=0; $i < $exampleDiv->length; $i++) { @@ -245,5 +237,4 @@ public function processFile($file, $parseExamples, $result = null) { return $result; } - } \ No newline at end of file diff --git a/src/Utils.php b/src/Utils.php index a1cd469..6766a91 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -4,34 +4,15 @@ class Utils { - public static function simplifyString($str) { + public static function simplifyString($str) + { $str = preg_replace(array("/\n+/", "/ {2,}/"), ' ', $str); $str = trim($str); return $str; } -// public static function is_class($name) { -// if (strpos($name, '::') !== false || strpos($name, '->') !== false) { -// return true; -// } else { -// return false; -// } -// } - -// public static function rewrite_names($name) { -// global $rewritename; -// $lname = strtolower($name); -// foreach ($rewritename as $pattern => $newName) { -// if (substr($lname, 0, strlen($pattern)) == $pattern) { -// $name = substr($newName, 0, strlen($pattern)) . substr($name, strlen($pattern)); -// } -// } -// return $name; -// } - - - - public static function clearSourceCode($source) { + public static function clearSourceCode($source) + { $source = trim(html_entity_decode(strip_tags(str_replace(array('
', '
', '
'), "\n", $source)))); if (substr($source, 0, 5) == 'length == 0) { @@ -94,7 +76,8 @@ public static function extractFormattedText($elms, $xpath = null) { return self::simplifyString(implode('\n\n', $textParts)); } - static public function convertSize($size) { + static public function convertSize($size) + { // http://stackoverflow.com/questions/11807115/php-convert-kb-mb-gb-tb-etc-to-bytes $number = substr($size, 0, -1); switch(strtoupper(substr($size,-1))){ @@ -108,15 +91,4 @@ static public function convertSize($size) { return $size; } } - -// static public function toFixedArray($array) { -// $fixed = \SplFixedArray::fromArray($array, true); -// -// foreach ($fixed as $key => $value) { -// if (is_array($value)) { -// $fixed[$key] = self::toFixedArray($value); -// } -// } -// return $fixed; -// } } diff --git a/tests/AvailabilityTest.php b/tests/AvailabilityTest.php new file mode 100644 index 0000000..0c67485 --- /dev/null +++ b/tests/AvailabilityTest.php @@ -0,0 +1,23 @@ + 'English', + 'es' => 'Spanish', + 'de' => 'German', + ]; + + $avail = new Availability(); + $languages = $avail->listPackages(); + + $this->assertArraySubset($expected, $languages); + } +} \ No newline at end of file diff --git a/tests/PackageTest.php b/tests/PackageTest.php new file mode 100644 index 0000000..d820c59 --- /dev/null +++ b/tests/PackageTest.php @@ -0,0 +1,46 @@ +assertEquals('php_manual_en.tar.gz', $package->getOrigFilename()); + } + + public function testGetUrl() + { + $package = new Package('en', 'cz1.php.net'); + $this->assertEquals('http://cz1.php.net/get/php_manual_en.tar.gz/from/this/mirror', $package->getUrl()); + } + + public function testUnpack() + { + $expectedFiles = [ + 'class.pdo.html', + 'class.splheap.html', + 'datetime.diff.html', + 'function.cos.html', + 'function.is-string.html', + 'function.print-r.html', + 'function.strcmp.html', + ]; + + $package = new Package('en', 'cz1.php.net'); + $tmpFile = $package->download(); + $dir = $package->unpack($expectedFiles); + + $unpackedFiles = scandir($dir); + foreach ($expectedFiles as $file) { + $this->assertContains($file, $unpackedFiles); + } + + $package->cleanup(); + $this->assertFileNotExists($tmpFile); + } +} \ No newline at end of file diff --git a/tests/ParserTest.php b/tests/ParserTest.php new file mode 100644 index 0000000..c1f9121 --- /dev/null +++ b/tests/ParserTest.php @@ -0,0 +1,42 @@ + 'datetime.setdate.json', + 'eventhttp.setcallback.html' => 'eventhttp.setcallback.json', + 'function.array-diff.html' => 'function.array-diff.json', + 'function.chown.html' => 'function.chown.json', + 'function.json-encode.html' => 'function.json-encode.json', + 'function.str-replace.html' => 'function.str-replace.json', + 'function.strrpos.html' => 'function.strrpos.json', + 'function.strtr.html' => 'function.strtr.json', + 'reflectionclass.getname.html' => 'reflectionclass.getname.json', + 'splfileobject.fgetcsv.html' => 'splfileobject.fgetcsv.json', + ]; + + $parser = new Parser(); + + foreach ($expectedFiles as $file => $jsonFile) { + $parserResult = $parser->processFile(self::TEST_FILES_DIR . DIRECTORY_SEPARATOR . $file); + $expected = json_decode(file_get_contents(self::TEST_FILES_DIR . DIRECTORY_SEPARATOR . $jsonFile), true); + + $funcName = $parserResult->getFuncNames()[0]; + $actual = $parserResult->getResult($funcName); + $actual['examples'] = $parserResult->getExamples($funcName); + + $this->assertEquals($expected, $actual); + } + } + +} diff --git a/tests/test-manual-files/datetime.setdate.html b/tests/test-manual-files/datetime.setdate.html new file mode 100644 index 0000000..8fd7563 --- /dev/null +++ b/tests/test-manual-files/datetime.setdate.html @@ -0,0 +1,192 @@ + + + + + Sets the date + + +
+
+

DateTime::setDate

+

date_date_set

+

(PHP 5 >= 5.2.0)

DateTime::setDate -- date_date_setSets the date

+ +
+ +
+

Description

+

Object oriented style

+
+ public DateTime DateTime::setDate + ( int $year + , int $month + , int $day + )
+ +

Procedural style

+
+ DateTime date_date_set + ( DateTime $object + , int $year + , int $month + , int $day + )
+ +

+ Resets the current date of the DateTime object to a different date. +

+
+ + +
+

Parameters

+
+ +
+object
+ +
+

Procedural style only: A DateTime object +returned by date_create(). +The function modifies this object.

+ + +
+year
+ +
+ +

+ Year of the date. +

+
+ + + +
+month
+ +
+ +

+ Month of the date. +

+
+ + + +
+day
+ +
+ +

+ Day of the date. +

+
+ + +
+ +
+ + +
+

Return Values

+

+ Returns the DateTime object for method chaining or FALSE on failure. +

+
+ + +
+

Changelog

+ + + + + + + + + + + + + + + +
VersionDescription
5.3.0Changed the +return value on success from NULL to DateTime.
+ +
+ + +
+

Examples

+
+

Example #1 DateTime::setDate() example

+

Object oriented style

+
+
+<?php
$date 
= new DateTime();
$date->setDate(200123);
echo 
$date->format('Y-m-d');
?> +
+
+
+ +

Procedural style

+
+
+<?php
$date 
date_create();
date_date_set($date200123);
echo 
date_format($date'Y-m-d');
?> +
+
+
+ +

The above examples will output:

+
+
+2001-02-03
+
+
+
+
+

Example #2 Values exceeding ranges are added to their parent values

+
+
+<?php
$date 
= new DateTime();

$date->setDate(2001228);
echo 
$date->format('Y-m-d') . "\n";

$date->setDate(2001229);
echo 
$date->format('Y-m-d') . "\n";

$date->setDate(2001143);
echo 
$date->format('Y-m-d') . "\n";
?> +
+
+
+ +

The above example will output:

+
+
+2001-02-28
+2001-03-01
+2002-02-03
+
+
+
+
+ + +
+

See Also

+ +
+ + +

diff --git a/tests/test-manual-files/datetime.setdate.json b/tests/test-manual-files/datetime.setdate.json new file mode 100644 index 0000000..0dfb2c2 --- /dev/null +++ b/tests/test-manual-files/datetime.setdate.json @@ -0,0 +1,79 @@ +{ + "desc": "Sets the date.", + "long_desc": "Resets the current date of the DateTime object to a different date.", + "ver": "PHP 5 >= 5.2.0", + "ret_desc": "Returns the DateTime object for method chaining or FALSE on failure.", + "seealso": [ + "DateTime::setISODate", + "DateTime::setTime" + ], + "filename": "datetime.setdate", + "params": [ + { + "list": [ + { + "type": "int", + "var": "$year", + "beh": "required", + "desc": "Year of the date." + }, + { + "type": "int", + "var": "$month", + "beh": "required", + "desc": "Month of the date." + }, + { + "type": "int", + "var": "$day", + "beh": "required", + "desc": "Day of the date." + } + ], + "name": "DateTime::setDate", + "ret_type": "DateTime" + }, + { + "list": [ + { + "type": "DateTime", + "var": "$object", + "beh": "required", + "desc": "Procedural style only: A DateTime object returned by date\\_create(). The function modifies this object." + }, + { + "type": "int", + "var": "$year", + "beh": "required", + "desc": "Year of the date." + }, + { + "type": "int", + "var": "$month", + "beh": "required", + "desc": "Month of the date." + }, + { + "type": "int", + "var": "$day", + "beh": "required", + "desc": "Day of the date." + } + ], + "name": "date_date_set", + "ret_type": "DateTime" + } + ], + "examples": [ + { + "title": "DateTime::setDate() example", + "source": "$date = new DateTime();\n$date->setDate(2001, 2, 3);\necho $date->format('Y-m-d');", + "output": "2001-02-03" + }, + { + "title": "Values exceeding ranges are added to their parent values", + "source": "$date = new DateTime();\n\n$date->setDate(2001, 2, 28);\necho $date->format('Y-m-d') . \"\\n\";\n\n$date->setDate(2001, 2, 29);\necho $date->format('Y-m-d') . \"\\n\";\n\n$date->setDate(2001, 14, 3);\necho $date->format('Y-m-d') . \"\\n\";", + "output": "2001-02-28\n2001-03-01\n2002-02-03" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/eventhttp.setcallback.html b/tests/test-manual-files/eventhttp.setcallback.html new file mode 100644 index 0000000..db2940b --- /dev/null +++ b/tests/test-manual-files/eventhttp.setcallback.html @@ -0,0 +1,194 @@ + + + + + Sets a callback for specified URI + + +
+
+

EventHttp::setCallback

+

(PECL event >= 1.4.0-beta)

EventHttp::setCallbackSets a callback for specified URI

+ +
+
+

Description

+
+ public + void + EventHttp::setCallback + ( + string + $path + + , + string + $cb + + [, + string + $arg + + ] )
+ +

+ Sets a callback for specified URI. +

+
+ +
+

Parameters

+
+ + +
+ + path +
+ +
+ +

+ The path for which to invoke the callback. +

+
+ + + +
+ + cb +
+ +
+ +

+ The callback + callable + that gets invoked on requested + path + . It should match the following prototype: +

+
+ void + callback + ([ + EventHttpRequest + $req + = NULL + + [, + mixed + $arg + = NULL + + ]] )
+ +

+

+ + +
+ + req +
+ +
+ +

+ EventHttpRequest + object. +

+
+ + + +
+ + arg +
+ +
+ +

+ Custom data. +

+
+ + +
+ +

+
+ + + +
+ + arg +
+ +
+ +

+ Custom data. +

+
+ + +
+ +
+ +
+

Return Values

+

+ Returns TRUE on success. Otherwise FALSE. +

+
+ +
+

Examples

+
+

Example #1 + EventHttp::setCallback() example

+
+
+<?php
/*
 * Simple HTTP server.
 *
 * To test it:
 * 1) Run it on a port of your choice, e.g.:
 * $ php examples/http.php 8010
 * 2) In another terminal connect to some address on this port
 * and make GET or POST request(others are turned off here), e.g.:
 * $ nc -t 127.0.0.1 8010
 * POST /about HTTP/1.0
 * Content-Type: text/plain
 * Content-Length: 4
 * Connection: close
 * (press Enter)
 *
 * It will output
 * a=12
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 *
 * 3) See what the server outputs on the previous terminal window.
 */

function _http_dump($req$data) {
    static 
$counter      0;
    static 
$max_requests 2;

    if (++
$counter >= $max_requests)  {
        echo 
"Counter reached max requests $max_requests. Exiting\n";
        exit();
    }

    echo 
__METHOD__" called\n";
    echo 
"request:"var_dump($req);
    echo 
"data:"var_dump($data);

    echo 
"\n===== DUMP =====\n";
    echo 
"Command:"$req->getCommand(), PHP_EOL;
    echo 
"URI:"$req->getUri(), PHP_EOL;
    echo 
"Input headers:"var_dump($req->getInputHeaders());
    echo 
"Output headers:"var_dump($req->getOutputHeaders());

    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";

    echo 
"\n >> Reading input buffer ...\n";
    
$buf $req->getInputBuffer();
    while (
$s $buf->readLine(EventBuffer::EOL_ANY)) {
        echo 
$sPHP_EOL;
    }
    echo 
"No more data in the buffer\n";
}

function 
_http_about($req) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

function 
_http_default($req$data) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

$port 8010;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Invalid port");
}

$base = new EventBase();
$http = new EventHttp($base);
$http->setAllowedMethods(EventHttpRequest::CMD_GET EventHttpRequest::CMD_POST);

$http->setCallback("/dump""_http_dump", array(48));
$http->setCallback("/about""_http_about");
$http->setDefaultCallback("_http_default""custom data value");

$http->bind("0.0.0.0"8010);
$base->loop();
?> +
+
+
+ +

The above example will output +something similar to:

+
+
+a=12
+HTTP/1.0 200 OK
+Content-Type: text/html; charset=ISO-8859-1
+Connection: close
+
+
+
+
+ +
+

See Also

+ +
+ +

diff --git a/tests/test-manual-files/eventhttp.setcallback.json b/tests/test-manual-files/eventhttp.setcallback.json new file mode 100644 index 0000000..e57d52a --- /dev/null +++ b/tests/test-manual-files/eventhttp.setcallback.json @@ -0,0 +1,43 @@ +{ + "desc": "Sets a callback for specified URI.", + "long_desc": "Sets a callback for specified URI.", + "ver": "PECL event >= 1.4.0-beta", + "ret_desc": "Returns TRUE on success. Otherwise FALSE.", + "seealso": [ + "EventHttp::setDefaultCallback" + ], + "filename": "eventhttp.setcallback", + "params": [ + { + "list": [ + { + "type": "string", + "var": "$path", + "beh": "required", + "desc": "The path for which to invoke the callback." + }, + { + "type": "string", + "var": "$cb", + "beh": "required", + "desc": "The callback callable that gets invoked on requested `path` . It should match the following prototype:\\n\\nvoid callback ([ EventHttpRequest `$req` = NULL [, mixed `$arg` = NULL ]] )" + }, + { + "type": "string", + "var": "$arg", + "beh": "optional", + "desc": "Custom data." + } + ], + "name": "EventHttp::setCallback", + "ret_type": "void" + } + ], + "examples": [ + { + "title": "EventHttp::setCallback() example", + "source": "\/*\n * Simple HTTP server.\n *\n * To test it:\n * 1) Run it on a port of your choice, e.g.:\n * $ php examples\/http.php 8010\n * 2) In another terminal connect to some address on this port\n * and make GET or POST request(others are turned off here), e.g.:\n * $ nc -t 127.0.0.1 8010\n * POST \/about HTTP\/1.0\n * Content-Type: text\/plain\n * Content-Length: 4\n * Connection: close\n * (press Enter)\n *\n * It will output\n * a=12\n * HTTP\/1.0 200 OK\n * Content-Type: text\/html; charset=ISO-8859-1\n * Connection: close\n *\n * 3) See what the server outputs on the previous terminal window.\n *\/\n\nfunction _http_dump($req, $data) {\n static $counter = 0;\n static $max_requests = 2;\n\n if (++$counter >= $max_requests) {\n echo \"Counter reached max requests $max_requests. Exiting\\n\";\n exit();\n }\n\n echo __METHOD__, \" called\\n\";\n echo \"request:\"; var_dump($req);\n echo \"data:\"; var_dump($data);\n\n echo \"\\n===== DUMP =====\\n\";\n echo \"Command:\", $req->getCommand(), PHP_EOL;\n echo \"URI:\", $req->getUri(), PHP_EOL;\n echo \"Input headers:\"; var_dump($req->getInputHeaders());\n echo \"Output headers:\"; var_dump($req->getOutputHeaders());\n\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n\n echo \"\\n >> Reading input buffer ...\\n\";\n $buf = $req->getInputBuffer();\n while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {\n echo $s, PHP_EOL;\n }\n echo \"No more data in the buffer\\n\";\n}\n\nfunction _http_about($req) {\n echo __METHOD__, PHP_EOL;\n echo \"URI: \", $req->getUri(), PHP_EOL;\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n}\n\nfunction _http_default($req, $data) {\n echo __METHOD__, PHP_EOL;\n echo \"URI: \", $req->getUri(), PHP_EOL;\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n}\n\n$port = 8010;\nif ($argc > 1) {\n $port = (int) $argv[1];\n}\nif ($port <= 0 || $port > 65535) {\n exit(\"Invalid port\");\n}\n\n$base = new EventBase();\n$http = new EventHttp($base);\n$http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);\n\n$http->setCallback(\"\/dump\", \"_http_dump\", array(4, 8));\n$http->setCallback(\"\/about\", \"_http_about\");\n$http->setDefaultCallback(\"_http_default\", \"custom data value\");\n\n$http->bind(\"0.0.0.0\", 8010);\n$base->loop();", + "output": "a=12\nHTTP\/1.0 200 OK\nContent-Type: text\/html; charset=ISO-8859-1\nConnection: close" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.array-diff.html b/tests/test-manual-files/function.array-diff.html new file mode 100644 index 0000000..786b5dd --- /dev/null +++ b/tests/test-manual-files/function.array-diff.html @@ -0,0 +1,159 @@ + + + + + Computes the difference of arrays + + +
+
+

array_diff

+

(PHP 4 >= 4.0.1, PHP 5)

array_diffComputes the difference of arrays

+ +
+ +
+

Description

+
+ array array_diff + ( array $array1 + , array $array2 + [, array $... + ] )
+ +

+ Compares array1 against one or more other arrays and + returns the values in array1 that are not present in + any of the other arrays. +

+
+ + +
+

Parameters

+

+

+ + +
+array1
+ +
+ +

+ The array to compare from +

+
+ + + +
+array2
+ +
+ +

+ An array to compare against +

+
+ + + +
+...
+ +
+ +

+ More arrays to compare against +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns an array containing all the entries from + array1 that are not present in any of the other arrays. +

+
+ + +
+

Examples

+

+

+

Example #1 array_diff() example

+
+
+<?php
$array1 
= array("a" => "green""red""blue""red");
$array2 = array("b" => "green""yellow""red");
$result array_diff($array1$array2);

print_r($result);
?> +
+
+
+ +

+ Multiple occurrences in $array1 are all + treated the same way. This will output : +

+
+
+Array
+(
+    [1] => blue
+)
+
+
+
+

+
+ + +
+

Notes

+

Note: +

+ Two elements are considered equal if and only if + (string) $elem1 === (string) $elem2. In words: + when the string representation is the same. + +

+

+

Note: +

+ This function only checks one dimension of a n-dimensional + array. Of course you can check deeper dimensions by using + array_diff($array1[0], $array2[0]);. +

+

+
+ + +
+

See Also

+

+

+

+
+ + +

diff --git a/tests/test-manual-files/function.array-diff.json b/tests/test-manual-files/function.array-diff.json new file mode 100644 index 0000000..0aa300f --- /dev/null +++ b/tests/test-manual-files/function.array-diff.json @@ -0,0 +1,45 @@ +{ + "desc": "Computes the difference of arrays.", + "long_desc": "Compares `array1` against one or more other arrays and returns the values in `array1` that are not present in any of the other arrays.", + "ver": "PHP 4 >= 4.0.1, PHP 5", + "ret_desc": "Returns an array containing all the entries from array1 that are not present in any of the other arrays.", + "seealso": [ + "array_diff_assoc", + "array_intersect", + "array_intersect_assoc" + ], + "filename": "function.array-diff", + "params": [ + { + "name": "array_diff", + "list": [ + { + "type": "array", + "var": "$array1", + "beh": "required", + "desc": "The array to compare from" + }, + { + "type": "array", + "var": "$array2", + "beh": "required", + "desc": "An array to compare against" + }, + { + "type": "array", + "var": "$...", + "beh": "optional", + "desc": "More arrays to compare against" + } + ], + "ret_type": "array" + } + ], + "examples": [ + { + "title": "array_diff() example", + "source": "$array1 = array(\"a\" => \"green\", \"red\", \"blue\", \"red\");\n$array2 = array(\"b\" => \"green\", \"yellow\", \"red\");\n$result = array_diff($array1, $array2);\n\nprint_r($result);", + "output": "Array\n(\n [1] => blue\n)" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.chown.html b/tests/test-manual-files/function.chown.html new file mode 100644 index 0000000..adfdfed --- /dev/null +++ b/tests/test-manual-files/function.chown.html @@ -0,0 +1,139 @@ + + + + + Changes file owner + + +
+
+

chown

+

(PHP 4, PHP 5)

chownChanges file owner

+ +
+ +
+

Description

+
+ bool chown + ( string $filename + , mixed $user + )
+ +

+ Attempts to change the owner of the file filename + to user user. Only the superuser may change the + owner of a file. +

+
+ + +
+

Parameters

+

+

+ + +
+filename
+ +
+ +

+ Path to the file. +

+
+ + + +
+user
+ +
+ +

+ A user name or number. +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns TRUE on success or FALSE on failure. +

+
+ + +
+

Examples

+

+

+

Example #1 Simple chown() usage

+
+
+<?php

// File name and username to use
$file_name"foo.php";
$path "/home/sites/php.net/public_html/sandbox/" $file_name ;
$user_name "root";

// Set the user
chown($path$user_name);

// Check the result
$stat stat($path);
print_r(posix_getpwuid($stat['uid']));

?> +
+
+
+ +

The above example will output +something similar to:

+
+
+Array
+(
+    [name] => root
+    [passwd] => x
+    [uid] => 0
+    [gid] => 0
+    [gecos] => root
+    [dir] => /root
+    [shell] => /bin/bash
+)
+
+
+
+

+
+ + +
+

Notes

+

Note: This function will not work on +remote files as the file to +be examined must be accessible via the server's filesystem.

+

Note: When safe mode is enabled, PHP checks whether +the files or directories being operated upon have the same UID (owner) as the +script that is being executed.

+
+ + +
+

See Also

+

+

+

+
+ + +

diff --git a/tests/test-manual-files/function.chown.json b/tests/test-manual-files/function.chown.json new file mode 100644 index 0000000..221d081 --- /dev/null +++ b/tests/test-manual-files/function.chown.json @@ -0,0 +1,37 @@ +{ + "desc": "Changes file owner.", + "long_desc": "Attempts to change the owner of the file `filename` to user `user`. Only the superuser may change the owner of a file.", + "ver": "PHP 4, PHP 5", + "ret_desc": "Returns TRUE on success or FALSE on failure.", + "seealso": [ + "chmod", "chgrp" + ], + "filename": "function.chown", + "params": [ + { + "name": "chown", + "list": [ + { + "type": "string", + "var": "$filename", + "beh": "required", + "desc": "Path to the file." + }, + { + "type": "mixed", + "var": "$user", + "beh": "required", + "desc": "A user name or number." + } + ], + "ret_type": "bool" + } + ], + "examples": [ + { + "title": "Simple chown() usage", + "source": "\/\/ File name and username to use\n$file_name= \"foo.php\";\n$path = \"\/home\/sites\/php.net\/public_html\/sandbox\/\" . $file_name ;\n$user_name = \"root\";\n\n\/\/ Set the user\nchown($path, $user_name);\n\n\/\/ Check the result\n$stat = stat($path);\nprint_r(posix_getpwuid($stat['uid']));", + "output": "Array\n(\n [name] => root\n [passwd] => x\n [uid] => 0\n [gid] => 0\n [gecos] => root\n [dir] => \/root\n [shell] => \/bin\/bash\n)" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.json-encode.html b/tests/test-manual-files/function.json-encode.html new file mode 100644 index 0000000..7e9375d --- /dev/null +++ b/tests/test-manual-files/function.json-encode.html @@ -0,0 +1,391 @@ + + + + + Returns the JSON representation of a value + + +
+
+

json_encode

+

(PHP 5 >= 5.2.0, PECL json >= 1.2.0)

json_encodeReturns the JSON representation of a value

+ +
+ +
+

Description

+
+ string json_encode + ( mixed $value + [, int $options = 0 + [, int $depth = 512 + ]] )
+ +

+ Returns a string containing the JSON representation of + value. +

+
+ + +
+

Parameters

+

+

+ + +
+value
+ +
+ +

+ The value being encoded. Can be any type except + a resource. +

+

+ All string data must be UTF-8 encoded. +

+ +

Note: +

+ PHP implements a superset of JSON as specified in the original + » RFC 4627 - it will also encode and + decode scalar types and NULL. RFC 4627 only supports these values when + they are nested inside an array or an object. +

+

+ Although this superset is consistent with the expanded definition of "JSON + text" in the newer » RFC 7159 (which + aims to supersede RFC 4627) and + » ECMA-404, this may cause + interoperability issues with older JSON parsers that adhere strictly to RFC + 4627 when encoding a single scalar value. +

+

+ +
+ + + +
+options
+ +
+ +

+ Bitmask consisting of JSON_HEX_QUOT, + JSON_HEX_TAG, + JSON_HEX_AMP, + JSON_HEX_APOS, + JSON_NUMERIC_CHECK, + JSON_PRETTY_PRINT, + JSON_UNESCAPED_SLASHES, + JSON_FORCE_OBJECT, + JSON_PRESERVE_ZERO_FRACTION, + JSON_UNESCAPED_UNICODE. The behaviour of these + constants is described on the + JSON constants page. +

+
+ + + +
+depth
+ +
+ +

+ Set the maximum depth. Must be greater than zero. +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns a JSON encoded string on success or FALSE on failure. +

+
+ + +
+

Changelog

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionDescription
5.6.6 + JSON_PRESERVE_ZERO_FRACTION option was added. +
5.5.0 + depth parameter was added. +
5.4.0 + JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, and JSON_UNESCAPED_UNICODE options were added. +
5.3.3 + JSON_NUMERIC_CHECK option was added. +
5.3.0 + The options parameter was added. +
+ +

+
+ + +
+

Examples

+

+

+

Example #1 A json_encode() example

+
+
+<?php
$arr 
= array('a' => 1'b' => 2'c' => 3'd' => 4'e' => 5);

echo 
json_encode($arr);
?> +
+
+
+ +

The above example will output:

+
+
+{"a":1,"b":2,"c":3,"d":4,"e":5}
+
+
+
+ +
+

Example #2 + A json_encode() example showing some options in use +

+
+
+<?php
$a 
= array('<foo>',"'bar'",'"baz"','&blong&'"\xc3\xa9");

echo 
"Normal: ",  json_encode($a), "\n";
echo 
"Tags: ",    json_encode($aJSON_HEX_TAG), "\n";
echo 
"Apos: ",    json_encode($aJSON_HEX_APOS), "\n";
echo 
"Quot: ",    json_encode($aJSON_HEX_QUOT), "\n";
echo 
"Amp: ",     json_encode($aJSON_HEX_AMP), "\n";
echo 
"Unicode: "json_encode($aJSON_UNESCAPED_UNICODE), "\n";
echo 
"All: ",     json_encode($aJSON_HEX_TAG JSON_HEX_APOS JSON_HEX_QUOT JSON_HEX_AMP JSON_UNESCAPED_UNICODE), "\n\n";

$b = array();

echo 
"Empty array output as array: "json_encode($b), "\n";
echo 
"Empty array output as object: "json_encode($bJSON_FORCE_OBJECT), "\n\n";

$c = array(array(1,2,3));

echo 
"Non-associative array output as array: "json_encode($c), "\n";
echo 
"Non-associative array output as object: "json_encode($cJSON_FORCE_OBJECT), "\n\n";

$d = array('foo' => 'bar''baz' => 'long');

echo 
"Associative array always output as object: "json_encode($d), "\n";
echo 
"Associative array always output as object: "json_encode($dJSON_FORCE_OBJECT), "\n\n";
?> +
+
+
+ +

The above example will output:

+
+
+Normal: ["<foo>","'bar'","\"baz\"","&blong&","\u00e9"]
+Tags: ["\u003Cfoo\u003E","'bar'","\"baz\"","&blong&","\u00e9"]
+Apos: ["<foo>","\u0027bar\u0027","\"baz\"","&blong&","\u00e9"]
+Quot: ["<foo>","'bar'","\u0022baz\u0022","&blong&","\u00e9"]
+Amp: ["<foo>","'bar'","\"baz\"","\u0026blong\u0026","\u00e9"]
+Unicode: ["<foo>","'bar'","\"baz\"","&blong&","Ă©"]
+All: ["\u003Cfoo\u003E","\u0027bar\u0027","\u0022baz\u0022","\u0026blong\u0026","Ă©"]
+
+Empty array output as array: []
+Empty array output as object: {}
+
+Non-associative array output as array: [[1,2,3]]
+Non-associative array output as object: {"0":{"0":1,"1":2,"2":3}}
+
+Associative array always output as object: {"foo":"bar","baz":"long"}
+Associative array always output as object: {"foo":"bar","baz":"long"}
+
+
+
+
+

Example #3 JSON_NUMERIC_CHECK option example

+
+
+<?php
echo "Strings representing numbers automatically turned into numbers".PHP_EOL;
$numbers = array('+123123''-123123''1.2e3''0.00001');
var_dump(
 
$numbers,
 
json_encode($numbersJSON_NUMERIC_CHECK)
);
echo 
"Strings containing improperly formatted numbers".PHP_EOL;
$strings = array('+a33123456789''a123');
var_dump(
 
$strings,
 
json_encode($stringsJSON_NUMERIC_CHECK)
);
?> +
+
+
+ +

The above example will output:

+
+
+Strings representing numbers automatically turned into numbers
+array(4) {
+  [0]=>
+  string(7) "+123123"
+  [1]=>
+  string(7) "-123123"
+  [2]=>
+  string(5) "1.2e3"
+  [3]=>
+  string(7) "0.00001"
+}
+string(28) "[123123,-123123,1200,1.0e-5]"
+Strings containing improperly formatted numbers
+array(2) {
+  [0]=>
+  string(13) "+a33123456789"
+  [1]=>
+  string(4) "a123"
+}
+string(24) "["+a33123456789","a123"]"
+
+
+
+
+

Example #4 Sequential versus non-sequential array example

+
+
+<?php
echo "Sequential array".PHP_EOL;
$sequential = array("foo""bar""baz""blong");
var_dump(
 
$sequential,
 
json_encode($sequential)
);

echo 
PHP_EOL."Non-sequential array".PHP_EOL;
$nonsequential = array(1=>"foo"2=>"bar"3=>"baz"4=>"blong");
var_dump(
 
$nonsequential,
 
json_encode($nonsequential)
);

echo 
PHP_EOL."Sequential array with one key unset".PHP_EOL;
unset(
$sequential[1]);
var_dump(
 
$sequential,
 
json_encode($sequential)
);
?> +
+
+
+ +

The above example will output:

+
+
+Sequential array
+array(4) {
+  [0]=>
+  string(3) "foo"
+  [1]=>
+  string(3) "bar"
+  [2]=>
+  string(3) "baz"
+  [3]=>
+  string(5) "blong"
+}
+string(27) "["foo","bar","baz","blong"]"
+
+Non-sequential array
+array(4) {
+  [1]=>
+  string(3) "foo"
+  [2]=>
+  string(3) "bar"
+  [3]=>
+  string(3) "baz"
+  [4]=>
+  string(5) "blong"
+}
+string(43) "{"1":"foo","2":"bar","3":"baz","4":"blong"}"
+
+Sequential array with one key unset
+array(3) {
+  [0]=>
+  string(3) "foo"
+  [2]=>
+  string(3) "baz"
+  [3]=>
+  string(5) "blong"
+}
+string(33) "{"0":"foo","2":"baz","3":"blong"}"
+
+
+
+
+

Example #5 JSON_PRESERVE_ZERO_FRACTION option example

+
+
+<?php
var_dump
(json_encode(12.0JSON_PRESERVE_ZERO_FRACTION));
var_dump(json_encode(12.0));
?> +
+
+
+ +

The above example will output:

+
+
+string(4) "12.0"
+string(2) "12"
+
+
+
+

+
+ + +
+

Notes

+

Note: +

+ In the event of a failure to encode, json_last_error() + can be used to determine the exact nature of the error. +

+

+

Note: +

+ When encoding an array, if the keys are not a continuous numeric + sequence starting from 0, all keys are encoded as strings, and + specified explicitly for each key-value pair. +

+

+

Note: +

+ Like the reference JSON encoder, json_encode() will + generate JSON that is a simple value (that is, neither an object nor an + array) if given a string, integer, + float or boolean as an input + value. While most decoders will accept these values + as valid JSON, some may not, as the specification is ambiguous on this + point. +

+

+ To summarise, always test that your JSON decoder can handle the output you + generate from json_encode(). +

+

+
+ + +
+

See Also

+

+

+

+
+ +

diff --git a/tests/test-manual-files/function.json-encode.json b/tests/test-manual-files/function.json-encode.json new file mode 100644 index 0000000..6614533 --- /dev/null +++ b/tests/test-manual-files/function.json-encode.json @@ -0,0 +1,65 @@ +{ + "desc": "Returns the JSON representation of a value.", + "long_desc": "Returns a string containing the JSON representation of `value`.", + "ver": "PHP 5 >= 5.2.0, PECL json >= 1.2.0", + "ret_desc": "Returns a JSON encoded string on success or FALSE on failure.", + "seealso": [ + "JsonSerializable", "json_decode", "json_last_error", "serialize" + ], + "filename": "function.json-encode", + "params": [ + { + "name": "json_encode", + "list": [ + { + "type": "mixed", + "var": "$value", + "beh": "required", + "desc": "The `value` being encoded. Can be any type except a resource.\\n\\nAll string data must be UTF-8 encoded.\\n\\n**Note**: PHP implements a superset of JSON as specified in the original \u00bb\u00a0RFC 4627 - it will also encode and decode scalar types and `NULL`. RFC 4627 only supports these values when they are nested inside an array or an object. Although this superset is consistent with the expanded definition of \"JSON text\" in the newer \u00bb\u00a0RFC 7159 (which aims to supersede RFC 4627) and \u00bb\u00a0ECMA-404, this may cause interoperability issues with older JSON parsers that adhere strictly to RFC 4627 when encoding a single scalar value." + }, + { + "type": "int", + "var": "$options", + "beh": "optional", + "desc": "Bitmask consisting of `JSON_HEX_QUOT`, `JSON_HEX_TAG`, `JSON_HEX_AMP`, `JSON_HEX_APOS`, `JSON_NUMERIC_CHECK`, `JSON_PRETTY_PRINT`, `JSON_UNESCAPED_SLASHES`, `JSON_FORCE_OBJECT`, `JSON_PRESERVE_ZERO_FRACTION`, `JSON_UNESCAPED_UNICODE`. The behaviour of these constants is described on the JSON constants page.", + "default": 0 + }, + { + "type": "int", + "var": "$depth", + "beh": "optional", + "desc": "Set the maximum depth. Must be greater than zero.", + "default": 512 + } + ], + "ret_type": "string" + } + ], + "examples": [ + { + "title": "A json_encode() example", + "source": "$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);\n\necho json_encode($arr);", + "output": "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}" + }, + { + "title": "A json_encode() example showing some options in use", + "source": "$a = array('',\"'bar'\",'\"baz\"','&blong&', \"\\xc3\\xa9\");\n\necho \"Normal: \", json_encode($a), \"\\n\";\necho \"Tags: \", json_encode($a, JSON_HEX_TAG), \"\\n\";\necho \"Apos: \", json_encode($a, JSON_HEX_APOS), \"\\n\";\necho \"Quot: \", json_encode($a, JSON_HEX_QUOT), \"\\n\";\necho \"Amp: \", json_encode($a, JSON_HEX_AMP), \"\\n\";\necho \"Unicode: \", json_encode($a, JSON_UNESCAPED_UNICODE), \"\\n\";\necho \"All: \", json_encode($a, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE), \"\\n\\n\";\n\n$b = array();\n\necho \"Empty array output as array: \", json_encode($b), \"\\n\";\necho \"Empty array output as object: \", json_encode($b, JSON_FORCE_OBJECT), \"\\n\\n\";\n\n$c = array(array(1,2,3));\n\necho \"Non-associative array output as array: \", json_encode($c), \"\\n\";\necho \"Non-associative array output as object: \", json_encode($c, JSON_FORCE_OBJECT), \"\\n\\n\";\n\n$d = array('foo' => 'bar', 'baz' => 'long');\n\necho \"Associative array always output as object: \", json_encode($d), \"\\n\";\necho \"Associative array always output as object: \", json_encode($d, JSON_FORCE_OBJECT), \"\\n\\n\";", + "output": "Normal: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nTags: [\"\\u003Cfoo\\u003E\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nApos: [\"\",\"\\u0027bar\\u0027\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nQuot: [\"\",\"'bar'\",\"\\u0022baz\\u0022\",\"&blong&\",\"\\u00e9\"]\nAmp: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"\\u0026blong\\u0026\",\"\\u00e9\"]\nUnicode: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\u00e9\"]\nAll: [\"\\u003Cfoo\\u003E\",\"\\u0027bar\\u0027\",\"\\u0022baz\\u0022\",\"\\u0026blong\\u0026\",\"\u00e9\"]\n\nEmpty array output as array: []\nEmpty array output as object: {}\n\nNon-associative array output as array: [[1,2,3]]\nNon-associative array output as object: {\"0\":{\"0\":1,\"1\":2,\"2\":3}}\n\nAssociative array always output as object: {\"foo\":\"bar\",\"baz\":\"long\"}\nAssociative array always output as object: {\"foo\":\"bar\",\"baz\":\"long\"}" + }, + { + "title": "JSON_NUMERIC_CHECK option example", + "source": "echo \"Strings representing numbers automatically turned into numbers\".PHP_EOL;\n$numbers = array('+123123', '-123123', '1.2e3', '0.00001');\nvar_dump(\n $numbers,\n json_encode($numbers, JSON_NUMERIC_CHECK)\n);\necho \"Strings containing improperly formatted numbers\".PHP_EOL;\n$strings = array('+a33123456789', 'a123');\nvar_dump(\n $strings,\n json_encode($strings, JSON_NUMERIC_CHECK)\n);", + "output": "Strings representing numbers automatically turned into numbers\narray(4) {\n [0]=>\n string(7) \"+123123\"\n [1]=>\n string(7) \"-123123\"\n [2]=>\n string(5) \"1.2e3\"\n [3]=>\n string(7) \"0.00001\"\n}\nstring(28) \"[123123,-123123,1200,1.0e-5]\"\nStrings containing improperly formatted numbers\narray(2) {\n [0]=>\n string(13) \"+a33123456789\"\n [1]=>\n string(4) \"a123\"\n}\nstring(24) \"[\"+a33123456789\",\"a123\"]\"" + }, + { + "title": "Sequential versus non-sequential array example", + "source": "echo \"Sequential array\".PHP_EOL;\n$sequential = array(\"foo\", \"bar\", \"baz\", \"blong\");\nvar_dump(\n $sequential,\n json_encode($sequential)\n);\n\necho PHP_EOL.\"Non-sequential array\".PHP_EOL;\n$nonsequential = array(1=>\"foo\", 2=>\"bar\", 3=>\"baz\", 4=>\"blong\");\nvar_dump(\n $nonsequential,\n json_encode($nonsequential)\n);\n\necho PHP_EOL.\"Sequential array with one key unset\".PHP_EOL;\nunset($sequential[1]);\nvar_dump(\n $sequential,\n json_encode($sequential)\n);", + "output": "Sequential array\narray(4) {\n [0]=>\n string(3) \"foo\"\n [1]=>\n string(3) \"bar\"\n [2]=>\n string(3) \"baz\"\n [3]=>\n string(5) \"blong\"\n}\nstring(27) \"[\"foo\",\"bar\",\"baz\",\"blong\"]\"\n\nNon-sequential array\narray(4) {\n [1]=>\n string(3) \"foo\"\n [2]=>\n string(3) \"bar\"\n [3]=>\n string(3) \"baz\"\n [4]=>\n string(5) \"blong\"\n}\nstring(43) \"{\"1\":\"foo\",\"2\":\"bar\",\"3\":\"baz\",\"4\":\"blong\"}\"\n\nSequential array with one key unset\narray(3) {\n [0]=>\n string(3) \"foo\"\n [2]=>\n string(3) \"baz\"\n [3]=>\n string(5) \"blong\"\n}\nstring(33) \"{\"0\":\"foo\",\"2\":\"baz\",\"3\":\"blong\"}\"" + }, + { + "title": "JSON_PRESERVE_ZERO_FRACTION option example", + "source": "var_dump(json_encode(12.0, JSON_PRESERVE_ZERO_FRACTION));\nvar_dump(json_encode(12.0));", + "output": "string(4) \"12.0\"\nstring(2) \"12\"" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.str-replace.html b/tests/test-manual-files/function.str-replace.html new file mode 100644 index 0000000..314e91e --- /dev/null +++ b/tests/test-manual-files/function.str-replace.html @@ -0,0 +1,201 @@ + + + + + Replace all occurrences of the search string with the replacement string + + +
+
+

str_replace

+

(PHP 4, PHP 5)

str_replaceReplace all occurrences of the search string with the replacement string

+ +
+ +
+

Description

+
+ mixed str_replace + ( mixed $search + , mixed $replace + , mixed $subject + [, int &$count + ] )
+ +

+ This function returns a string or an array with all occurrences of + search in subject + replaced with the given replace value. +

+

+ If you don't need fancy replacing rules (like regular expressions), you + should always use this function instead of preg_replace(). +

+
+ + +
+

Parameters

+

+ If search and replace are + arrays, then str_replace() takes a value from each array + and uses them to search and replace on subject. If + replace has fewer values than + search, then an empty string is used for the rest of + replacement values. If search is an array and + replace is a string, then this replacement string is + used for every value of search. The converse would + not make sense, though. +

+

+ If search or replace + are arrays, their elements are processed first to last. +

+

+

+ + +
+search
+ +
+ +

+ The value being searched for, otherwise known as the needle. + An array may be used to designate multiple needles. +

+
+ + + +
+replace
+ +
+ +

+ The replacement value that replaces found search + values. An array may be used to designate multiple replacements. +

+
+ + + +
+subject
+ +
+ +

+ The string or array being searched and replaced on, + otherwise known as the haystack. +

+

+ If subject is an array, then the search and + replace is performed with every entry of + subject, and the return value is an array as + well. +

+
+ + + +
+count
+ +
+ +

+ If passed, this will be set to the number of replacements performed. +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ This function returns a string or an array with the replaced values. +

+
+ + +
+

Examples

+

+

+

Example #1 Basic str_replace() examples

+
+
+<?php
// Provides: <body text='black'>
$bodytag str_replace("%body%""black""<body text='%body%'>");

// Provides: Hll Wrld f PHP
$vowels = array("a""e""i""o""u""A""E""I""O""U");
$onlyconsonants str_replace($vowels"""Hello World of PHP");

// Provides: You should eat pizza, beer, and ice cream every day
$phrase  "You should eat fruits, vegetables, and fiber every day.";
$healthy = array("fruits""vegetables""fiber");
$yummy   = array("pizza""beer""ice cream");

$newphrase str_replace($healthy$yummy$phrase);

// Provides: 2
$str str_replace("ll""""good golly miss molly!"$count);
echo 
$count;
?> +
+
+
+ +
+

+

+

+

Example #2 Examples of potential str_replace() gotchas

+
+
+<?php
// Order of replacement
$str     "Line 1\nLine 2\rLine 3\r\nLine 4\n";
$order   = array("\r\n""\n""\r");
$replace '<br />';

// Processes \r\n's first so they aren't converted twice.
$newstr str_replace($order$replace$str);

// Outputs F because A is replaced with B, then B is replaced with C, and so on...
// Finally E is replaced with F, because of left to right replacements.
$search  = array('A''B''C''D''E');
$replace = array('B''C''D''E''F');
$subject 'A';
echo 
str_replace($search$replace$subject);

// Outputs: apearpearle pear
// For the same reason mentioned above
$letters = array('a''p');
$fruit   = array('apple''pear');
$text    'a p';
$output  str_replace($letters$fruit$text);
echo 
$output;
?> +
+
+
+ +
+

+
+ + +
+

Notes

+

Note: This function is +binary-safe.

+
Caution +

Replacement order gotcha

+

+ Because str_replace() replaces left to right, it might + replace a previously inserted value when doing multiple replacements. + See also the examples in this document. +

+
+

Note: +

+ This function is case-sensitive. Use str_ireplace() + for case-insensitive replace. +

+

+
+ + +
+

See Also

+

+

+

+
+ + +

diff --git a/tests/test-manual-files/function.str-replace.json b/tests/test-manual-files/function.str-replace.json new file mode 100644 index 0000000..d942aea --- /dev/null +++ b/tests/test-manual-files/function.str-replace.json @@ -0,0 +1,57 @@ +{ + "desc": "Replace all occurrences of the search string with the replacement string.", + "long_desc": "This function returns a string or an array with all occurrences of `search` in `subject` replaced with the given `replace` value.\\n\\nIf you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg\\_replace().", + "ver": "PHP 4, PHP 5", + "ret_desc": "This function returns a string or an array with the replaced values.", + "seealso": [ + "str_ireplace", + "substr_replace", + "preg_replace", + "strtr" + ], + "filename": "function.str-replace", + "params": [ + { + "name": "str_replace", + "list": [ + { + "type": "mixed", + "var": "$search", + "beh": "required", + "desc": "The value being searched for, otherwise known as the needle`. An array may be used to designate multiple needles." + }, + { + "type": "mixed", + "var": "$replace", + "beh": "required", + "desc": "The replacement value that replaces found `search` values. An array may be used to designate multiple replacements." + }, + { + "type": "mixed", + "var": "$subject", + "beh": "required", + "desc": "The string or array being searched and replaced on, otherwise known as the haystack`.\\n\\nIf `subject` is an array, then the search and replace is performed with every entry of `subject`, and the return value is an array as well." + }, + { + "type": "int", + "var": "&$count", + "beh": "optional", + "desc": "If passed, this will be set to the number of replacements performed." + } + ], + "ret_type": "mixed" + } + ], + "examples": [ + { + "title": "Basic str_replace() examples", + "source": "\/\/ Provides: \n$bodytag = str_replace(\"%body%\", \"black\", \"\");\n\n\/\/ Provides: Hll Wrld f PHP\n$vowels = array(\"a\", \"e\", \"i\", \"o\", \"u\", \"A\", \"E\", \"I\", \"O\", \"U\");\n$onlyconsonants = str_replace($vowels, \"\", \"Hello World of PHP\");\n\n\/\/ Provides: You should eat pizza, beer, and ice cream every day\n$phrase = \"You should eat fruits, vegetables, and fiber every day.\";\n$healthy = array(\"fruits\", \"vegetables\", \"fiber\");\n$yummy = array(\"pizza\", \"beer\", \"ice cream\");\n\n$newphrase = str_replace($healthy, $yummy, $phrase);\n\n\/\/ Provides: 2\n$str = str_replace(\"ll\", \"\", \"good golly miss molly!\", $count);\necho $count;", + "output": null + }, + { + "title": "Examples of potential str_replace() gotchas", + "source": "\/\/ Order of replacement\n$str = \"Line 1\\nLine 2\\rLine 3\\r\\nLine 4\\n\";\n$order = array(\"\\r\\n\", \"\\n\", \"\\r\");\n$replace = '
';\n\n\/\/ Processes \\r\\n's first so they aren't converted twice.\n$newstr = str_replace($order, $replace, $str);\n\n\/\/ Outputs F because A is replaced with B, then B is replaced with C, and so on...\n\/\/ Finally E is replaced with F, because of left to right replacements.\n$search = array('A', 'B', 'C', 'D', 'E');\n$replace = array('B', 'C', 'D', 'E', 'F');\n$subject = 'A';\necho str_replace($search, $replace, $subject);\n\n\/\/ Outputs: apearpearle pear\n\/\/ For the same reason mentioned above\n$letters = array('a', 'p');\n$fruit = array('apple', 'pear');\n$text = 'a p';\n$output = str_replace($letters, $fruit, $text);\necho $output;", + "output": null + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.strrpos.html b/tests/test-manual-files/function.strrpos.html new file mode 100644 index 0000000..d22e578 --- /dev/null +++ b/tests/test-manual-files/function.strrpos.html @@ -0,0 +1,189 @@ + + + + + Find the position of the last occurrence of a substring in a string + + +
+
+

strrpos

+

(PHP 4, PHP 5)

strrposFind the position of the last occurrence of a substring in a string

+ +
+ +
+

Description

+
+ int strrpos + ( string $haystack + , string $needle + [, int $offset = 0 + ] )
+ +

+ Find the numeric position of the last occurrence of + needle in the haystack string. +

+
+ + +
+

Parameters

+

+

+ + +
+haystack
+ +
+ +

+ The string to search in. +

+
+ + + +
+needle
+ +
+ +

+ If needle is not a string, it is converted + to an integer and applied as the ordinal value of a character. +

+
+ + + +
+offset
+ +
+ +

+ If specified, search will start this number of characters counted from the + beginning of the string. If the value is negative, search will instead start + from that many characters from the end of the string, searching backwards. +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns the position where the needle exists relative to the beginnning of + the haystack string (independent of search direction + or offset). + Also note that string positions start at 0, and not 1. +

+

+ Returns FALSE if the needle was not found. +

+
Warning

This function may +return Boolean FALSE, but may also return a non-Boolean value which +evaluates to FALSE. Please read the section on Booleans for more +information. Use the === +operator for testing the return value of this +function.

+
+ + +
+

Changelog

+

+ + + + + + + + + + + + + + + + + + +
VersionDescription
5.0.0 + The needle may now be a string of more than one + character. +
+ +

+
+ + +
+

Examples

+

+

+

Example #1 Checking if a needle is in the haystack

+

+ It is easy to mistake the return values for "character found at + position 0" and "character not found". Here's how to detect + the difference: +

+
+
+<?php

$pos 
strrpos($mystring"b");
if (
$pos === false) { // note: three equal signs
    // not found...
}

?> +
+
+
+ +
+

+

+

+

Example #2 Searching with offsets

+
+
+<?php
$foo 
"0123456789a123456789b123456789c";

var_dump(strrpos($foo'7', -5));  // Starts looking backwards five positions
                                   // from the end. Result: int(17)

var_dump(strrpos($foo'7'20));  // Starts searching 20 positions into the
                                   // string. Result: int(27)

var_dump(strrpos($foo'7'28));  // Result: bool(false)
?> +
+
+
+ +
+

+
+ + +
+

See Also

+

+

    +
  • strpos() - Find the position of the first occurrence of a substring in a string
  • +
  • stripos() - Find the position of the first occurrence of a case-insensitive substring in a string
  • +
  • strripos() - Find the position of the last occurrence of a case-insensitive substring in a string
  • +
  • strrchr() - Find the last occurrence of a character in a string
  • +
  • substr() - Return part of a string
  • +
+

+
+ + +

diff --git a/tests/test-manual-files/function.strrpos.json b/tests/test-manual-files/function.strrpos.json new file mode 100644 index 0000000..3d16bda --- /dev/null +++ b/tests/test-manual-files/function.strrpos.json @@ -0,0 +1,53 @@ +{ + "desc": "Find the position of the last occurrence of a substring in a string.", + "long_desc": "Find the numeric position of the last occurrence of `needle` in the `haystack` string.", + "ver": "PHP 4, PHP 5", + "ret_desc": "Returns the position where the needle exists relative to the beginnning of the haystack string (independent of search direction or offset). Also note that string positions start at 0, and not 1.", + "seealso": [ + "strpos", + "stripos", + "strripos", + "strrchr", + "substr" + ], + "filename": "function.strrpos", + "params": [ + { + "name": "strrpos", + "list": [ + { + "type": "string", + "var": "$haystack", + "beh": "required", + "desc": "The string to search in." + }, + { + "type": "string", + "var": "$needle", + "beh": "required", + "desc": "If `needle` is not a string, it is converted to an integer and applied as the ordinal value of a character." + }, + { + "type": "int", + "var": "$offset", + "beh": "optional", + "desc": "If specified, search will start this number of characters counted from the beginning of the string. If the value is negative, search will instead start from that many characters from the end of the string, searching backwards.", + "default": 0 + } + ], + "ret_type": "int" + } + ], + "examples": [ + { + "title": "Checking if a needle is in the haystack", + "source": "$pos = strrpos($mystring, \"b\");\nif ($pos === false) { \/\/ note: three equal signs\n \/\/ not found...\n}", + "output": null + }, + { + "title": "Searching with offsets", + "source": "$foo = \"0123456789a123456789b123456789c\";\n\nvar_dump(strrpos($foo, '7', -5)); \/\/ Starts looking backwards five positions\n \/\/ from the end. Result: int(17)\n\nvar_dump(strrpos($foo, '7', 20)); \/\/ Starts searching 20 positions into the\n \/\/ string. Result: int(27)\n\nvar_dump(strrpos($foo, '7', 28)); \/\/ Result: bool(false)", + "output": null + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/function.strtr.html b/tests/test-manual-files/function.strtr.html new file mode 100644 index 0000000..0b1cb82 --- /dev/null +++ b/tests/test-manual-files/function.strtr.html @@ -0,0 +1,220 @@ + + + + + Translate characters or replace substrings + + +
+
+

strtr

+

(PHP 4, PHP 5, PHP 7)

strtrTranslate characters or replace substrings

+ +
+ +
+

Description

+
+ string strtr + ( string $str + , string $from + , string $to + )
+ +
+ string strtr + ( string $str + , array $replace_pairs + )
+ +

+ If given three arguments, this function returns a copy of + str where all occurrences of each (single-byte) + character in from have been translated to the + corresponding character in to, i.e., every + occurrence of $from[$n] has been replaced with + $to[$n], where $n is a valid + offset in both arguments. +

+

+ If from and to have + different lengths, the extra characters in the longer of the two + are ignored. The length of str will be the same as + the return value's. +

+

+ If given two arguments, the second should be an array in the + form array('from' => 'to', ...). The return value is + a string where all the occurrences of the array keys have been + replaced by the corresponding values. The longest keys will be tried first. + Once a substring has been replaced, its new value will not be searched + again. +

+

+ In this case, the keys and the values may have any length, provided that + there is no empty key; additionally, the length of the return value may + differ from that of str. + However, this function will be the most efficient when all the keys have the + same size. +

+
+ + +
+

Parameters

+

+

+ + +
+str
+ +
+ +

+ The string being translated. +

+
+ + + +
+from
+ +
+ +

+ The string being translated to to. +

+
+ + + +
+to
+ +
+ +

+ The string replacing from. +

+
+ + + +
+replace_pairs
+ +
+ +

+ The replace_pairs parameter may be used instead of + to and from, in which case it's an + array in the form array('from' => 'to', ...). +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns the translated string. +

+

+ If replace_pairs contains a key which + is an empty string (""), + FALSE will be returned. If the str is not a scalar + then it is not typecasted into a string, instead a warning is raised and + NULL is returned. +

+
+ + +
+

Examples

+

+

+

Example #1 strtr() example

+
+
+<?php
//In this form, strtr() does byte-by-byte translation
//Therefore, we are assuming a single-byte encoding here:
$addr strtr($addr"äåö""aao");
?> +
+
+
+ +
+

+

+ The next example shows the behavior of strtr() when + called with only two arguments. Note the preference of the replacements + ("h" is not picked because there are longer matches) + and how replaced text was not searched again. +

+
+

Example #2 strtr() example with two arguments

+
+
+<?php
$trans 
= array("h" => "-""hello" => "hi""hi" => "hello");
echo 
strtr("hi all, I said hello"$trans);
?> +
+
+
+ +

The above example will output:

+
+
+hello all, I said hi
+
+
+
+

+ The two modes of behavior are substantially different. With three arguments, + strtr() will replace bytes; with two, it may replace + longer substrings. +

+
+

Example #3 strtr() behavior comparison

+
+
+<?php
echo strtr("baab""ab""01"),"\n";

$trans = array("ab" => "01");
echo 
strtr("baab"$trans);
?> +
+
+
+ +

The above example will output:

+
+
+1001
+ba01
+
+
+
+
+ + +
+

See Also

+

+

    +
  • str_replace() - Replace all occurrences of the search string with the replacement string
  • +
  • preg_replace() - Perform a regular expression search and replace
  • +
+

+
+ +

diff --git a/tests/test-manual-files/function.strtr.json b/tests/test-manual-files/function.strtr.json new file mode 100644 index 0000000..3cb32ff --- /dev/null +++ b/tests/test-manual-files/function.strtr.json @@ -0,0 +1,72 @@ +{ + "desc": "Translate characters or replace substrings.", + "long_desc": "If given three arguments, this function returns a copy of `str` where all occurrences of each (single-byte) character in `from` have been translated to the corresponding character in `to`, i.e., every occurrence of `$from[$n]` has been replaced with `$to[$n]`, where `$n` is a valid offset in both arguments.\\n\\nIf `from` and `to` have different lengths, the extra characters in the longer of the two are ignored. The length of `str` will be the same as the return value's.\\n\\nIf given two arguments, the second should be an array in the form `array('from' => 'to', ...)`. The return value is a string where all the occurrences of the array keys have been replaced by the corresponding values. The longest keys will be tried first. Once a substring has been replaced, its new value will not be searched again.\\n\\nIn this case, the keys and the values may have any length, provided that there is no empty key; additionally, the length of the return value may differ from that of `str`. However, this function will be the most efficient when all the keys have the same size.", + "ver": "PHP 4, PHP 5, PHP 7", + "ret_desc": "Returns the translated string.", + "seealso": [ + "str_replace", + "preg_replace" + ], + "filename": "function.strtr", + "params": [ + { + "list": [ + { + "type": "string", + "var": "$str", + "beh": "required", + "desc": "The string being translated." + }, + { + "type": "string", + "var": "$from", + "beh": "required", + "desc": "The string being translated to `to`." + }, + { + "type": "string", + "var": "$to", + "beh": "required", + "desc": "The string replacing `from`." + } + ], + "name": "strtr", + "ret_type": "string" + }, + { + "list": [ + { + "type": "string", + "var": "$str", + "beh": "required", + "desc": "The string being translated." + }, + { + "type": "array", + "var": "$replace_pairs", + "beh": "required", + "desc": "The `replace_pairs` parameter may be used instead of `to` and `from`, in which case it's an array in the form `array('from' => 'to', ...)`." + } + ], + "name": "strtr", + "ret_type": "string" + } + ], + "examples": [ + { + "title": "strtr() example", + "source": "\/\/In this form, strtr() does byte-by-byte translation\n\/\/Therefore, we are assuming a single-byte encoding here:\n$addr = strtr($addr, \"\u00e4\u00e5\u00f6\", \"aao\");", + "output": null + }, + { + "title": "strtr() example with two arguments", + "source": "$trans = array(\"h\" => \"-\", \"hello\" => \"hi\", \"hi\" => \"hello\");\necho strtr(\"hi all, I said hello\", $trans);", + "output": "hello all, I said hi" + }, + { + "title": "strtr() behavior comparison", + "source": "echo strtr(\"baab\", \"ab\", \"01\"),\"\\n\";\n\n$trans = array(\"ab\" => \"01\");\necho strtr(\"baab\", $trans);", + "output": "1001\nba01" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/reflectionclass.getname.html b/tests/test-manual-files/reflectionclass.getname.html new file mode 100644 index 0000000..f915fbd --- /dev/null +++ b/tests/test-manual-files/reflectionclass.getname.html @@ -0,0 +1,98 @@ + + + + + Gets class name + + +
+
+

ReflectionClass::getName

+

(PHP 5)

ReflectionClass::getNameGets class name

+ +
+ +
+

Description

+
+ public string ReflectionClass::getName + ( void + )
+ +

+ Gets the class name. +

+ +
Warning

This function is +currently not documented; only its argument list is available. +

+ +
+ + +
+

Parameters

+

This function has no parameters.

+
+ + +
+

Return Values

+

+ The class name. +

+
+ + +
+

Examples

+

+

+

Example #1 ReflectionClass::getName() example

+
+
+<?php
namespace A\B;

class 
Foo { }

$function = new \ReflectionClass('stdClass');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());

$function = new \ReflectionClass('A\\B\\Foo');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());
?> +
+
+
+ +

The above example will output:

+
+
+bool(false)
+string(8) "stdClass"
+string(0) ""
+string(8) "stdClass"
+
+bool(true)
+string(7) "A\B\Foo"
+string(3) "A\B"
+string(3) "Foo"
+
+
+
+

+
+ + +
+

See Also

+

+

+

+
+ + +

diff --git a/tests/test-manual-files/reflectionclass.getname.json b/tests/test-manual-files/reflectionclass.getname.json new file mode 100644 index 0000000..9f7a842 --- /dev/null +++ b/tests/test-manual-files/reflectionclass.getname.json @@ -0,0 +1,24 @@ +{ + "desc": "Gets class name.", + "long_desc": "Gets the class name.\\n\\nThis function is currently not documented; only its argument list is available.", + "ver": "PHP 5", + "ret_desc": "The class name.", + "seealso": [ + "ReflectionClass::getNamespaceName" + ], + "filename": "reflectionclass.getname", + "params": [ + { + "name": "ReflectionClass::getName", + "list": [], + "ret_type": "string" + } + ], + "examples": [ + { + "title": "ReflectionClass::getName() example", + "source": "namespace A\\B;\n\nclass Foo { }\n\n$function = new \\ReflectionClass('stdClass');\n\nvar_dump($function->inNamespace());\nvar_dump($function->getName());\nvar_dump($function->getNamespaceName());\nvar_dump($function->getShortName());\n\n$function = new \\ReflectionClass('A\\\\B\\\\Foo');\n\nvar_dump($function->inNamespace());\nvar_dump($function->getName());\nvar_dump($function->getNamespaceName());\nvar_dump($function->getShortName());", + "output": "bool(false)\nstring(8) \"stdClass\"\nstring(0) \"\"\nstring(8) \"stdClass\"\n\nbool(true)\nstring(7) \"A\\B\\Foo\"\nstring(3) \"A\\B\"\nstring(3) \"Foo\"" + } + ] +} \ No newline at end of file diff --git a/tests/test-manual-files/splfileobject.fgetcsv.html b/tests/test-manual-files/splfileobject.fgetcsv.html new file mode 100644 index 0000000..d1571e0 --- /dev/null +++ b/tests/test-manual-files/splfileobject.fgetcsv.html @@ -0,0 +1,165 @@ + + + + + Gets line from file and parse as CSV fields + + +
+
+

SplFileObject::fgetcsv

+

(PHP 5 >= 5.1.0)

SplFileObject::fgetcsvGets line from file and parse as CSV fields

+ +
+ +
+

Description

+
+ public array SplFileObject::fgetcsv + ([ string $delimiter = "," + [, string $enclosure = "\"" + [, string $escape = "\\" + ]]] )
+ +

+ Gets a line from the file which is in CSV format and returns an array containing the fields read. +

+
+ + +
+

Parameters

+

+

+ + +
+delimiter
+ +
+ +

+ The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl(). +

+
+ + + +
+enclosure
+ +
+ +

+ The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl(). +

+
+ + + +
+escape
+ +
+ +

+ The escape character (one character only). Defaults as a backslash (\) or the value set using SplFileObject::setCsvControl(). +

+
+ + +
+ +

+
+ + +
+

Return Values

+

+ Returns an indexed array containing the fields read, or FALSE on error. +

+

Note: +

+ A blank line in a CSV file will be returned as an array + comprising a single NULL field unless using SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE, + in which case empty lines are skipped. +

+

+
+ + +
+

Examples

+

+

+

Example #1 SplFileObject::fgetcsv() example

+
+
+<?php
$file 
= new SplFileObject("data.csv");
while (!
$file->eof()) {
    
var_dump($file->fgetcsv());
}
?> +
+
+
+ +
+

+

+

+

Example #2 SplFileObject::READ_CSV example

+
+
+<?php
$file 
= new SplFileObject("animals.csv");
$file->setFlags(SplFileObject::READ_CSV);
foreach (
$file as $row) {
    list(
$animal$class$legs) = $row;
    
printf("A %s is a %s with %d legs\n"$animal$class$legs);
}
?> +
+
+
+ +

Contents of animals.csv

+
+
crocodile,reptile,4
+dolphin,mammal,0
+duck,bird,2
+koala,mammal,4
+salmon,fish,0
+
+
+ +

The above example will output +something similar to:

+
+
+A crocodile is a reptile with 4 legs
+A dolphin is a mammal with 0 legs
+A duck is a bird with 2 legs
+A koala is a mammal with 4 legs
+A salmon is a fish with 0 legs
+
+
+
+

+
+ + +
+

See Also

+

+

+

+
+ + +

diff --git a/tests/test-manual-files/splfileobject.fgetcsv.json b/tests/test-manual-files/splfileobject.fgetcsv.json new file mode 100644 index 0000000..44279ee --- /dev/null +++ b/tests/test-manual-files/splfileobject.fgetcsv.json @@ -0,0 +1,51 @@ +{ + "desc": "Gets line from file and parse as CSV fields.", + "long_desc": "Gets a line from the file which is in CSV format and returns an array containing the fields read.", + "ver": "PHP 5 >= 5.1.0", + "ret_desc": "Returns an indexed array containing the fields read, or FALSE on error.", + "seealso": [ + "SplFileObject::setCsvControl", "SplFileObject::setFlags", "SplFileObject::READ_CSV", "SplFileObject::current" + ], + "filename": "splfileobject.fgetcsv", + "params": [ + { + "name": "SplFileObject::fgetcsv", + "list": [ + { + "type": "string", + "var": "$delimiter", + "beh": "optional", + "desc": "The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl().", + "default": "\",\"" + }, + { + "type": "string", + "var": "$enclosure", + "beh": "optional", + "desc": "The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl().", + "default": "\"\\\"\"" + }, + { + "type": "string", + "var": "$escape", + "beh": "optional", + "desc": "The escape character (one character only). Defaults as a backslash (`\\`) or the value set using SplFileObject::setCsvControl().", + "default": "\"\\\\\"" + } + ], + "ret_type": "array" + } + ], + "examples": [ + { + "title": "SplFileObject::fgetcsv() example", + "source": "$file = new SplFileObject(\"data.csv\");\nwhile (!$file->eof()) {\n var_dump($file->fgetcsv());\n}", + "output": null + }, + { + "title": "SplFileObject::READ_CSV example", + "source": "$file = new SplFileObject(\"animals.csv\");\n$file->setFlags(SplFileObject::READ_CSV);\nforeach ($file as $row) {\n list($animal, $class, $legs) = $row;\n printf(\"A %s is a %s with %d legs\\n\", $animal, $class, $legs);\n}", + "output": "A crocodile is a reptile with 4 legs\nA dolphin is a mammal with 0 legs\nA duck is a bird with 2 legs\nA koala is a mammal with 4 legs\nA salmon is a fish with 0 legs" + } + ] +} \ No newline at end of file From 31517fe21a8ebc107035bc744dc48b5ce90bdbbf Mon Sep 17 00:00:00 2001 From: Martin Sikora Date: Mon, 21 Aug 2017 11:43:24 +0200 Subject: [PATCH 3/4] removed Behat, moved tests to PHPUnit --- .travis.yml | 8 +- features/bootstrap/FeatureContext.php | 21 - features/bootstrap/ParserResultContext.php | 84 ---- features/parser-result.feature | 16 - .../test-manual-files/datetime.setdate.html | 192 --------- .../test-manual-files/datetime.setdate.json | 79 ---- .../eventhttp.setcallback.html | 194 --------- .../eventhttp.setcallback.json | 43 -- .../function.array-diff.html | 159 ------- .../function.array-diff.json | 45 -- .../test-manual-files/function.chown.html | 139 ------- .../test-manual-files/function.chown.json | 37 -- .../function.json-encode.html | 391 ------------------ .../function.json-encode.json | 65 --- .../function.str-replace.html | 201 --------- .../function.str-replace.json | 57 --- .../test-manual-files/function.strrpos.html | 189 --------- .../test-manual-files/function.strrpos.json | 53 --- .../reflectionclass.getname.html | 98 ----- .../reflectionclass.getname.json | 24 -- .../splfileobject.fgetcsv.html | 165 -------- .../splfileobject.fgetcsv.json | 51 --- phpunit.xml | 7 + src/Parser.php | 35 +- tests/ParserResultTest.php | 83 ++++ 25 files changed, 110 insertions(+), 2326 deletions(-) delete mode 100644 features/bootstrap/FeatureContext.php delete mode 100644 features/bootstrap/ParserResultContext.php delete mode 100644 features/parser-result.feature delete mode 100644 features/test-manual-files/datetime.setdate.html delete mode 100644 features/test-manual-files/datetime.setdate.json delete mode 100644 features/test-manual-files/eventhttp.setcallback.html delete mode 100644 features/test-manual-files/eventhttp.setcallback.json delete mode 100644 features/test-manual-files/function.array-diff.html delete mode 100644 features/test-manual-files/function.array-diff.json delete mode 100644 features/test-manual-files/function.chown.html delete mode 100644 features/test-manual-files/function.chown.json delete mode 100644 features/test-manual-files/function.json-encode.html delete mode 100644 features/test-manual-files/function.json-encode.json delete mode 100644 features/test-manual-files/function.str-replace.html delete mode 100644 features/test-manual-files/function.str-replace.json delete mode 100644 features/test-manual-files/function.strrpos.html delete mode 100644 features/test-manual-files/function.strrpos.json delete mode 100644 features/test-manual-files/reflectionclass.getname.html delete mode 100644 features/test-manual-files/reflectionclass.getname.json delete mode 100644 features/test-manual-files/splfileobject.fgetcsv.html delete mode 100644 features/test-manual-files/splfileobject.fgetcsv.json create mode 100644 phpunit.xml create mode 100644 tests/ParserResultTest.php diff --git a/.travis.yml b/.travis.yml index 0d95f3a..7085abd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: php php: - - 5.4 - - 5.5 - - 5.6 + - '5.6' + - '7.0' + - '7.1' script: - - bin/behat + - vendor/bin/phpunit before_script: - composer self-update - composer install diff --git a/features/bootstrap/FeatureContext.php b/features/bootstrap/FeatureContext.php deleted file mode 100644 index 60a07ad..0000000 --- a/features/bootstrap/FeatureContext.php +++ /dev/null @@ -1,21 +0,0 @@ -useContext('availability_subcontext_alias', new AvailabilityContext()); - $this->useContext('package_subcontext_alias', new PackageContext()); - $this->useContext('parser_subcontext_alias', new ParserContext()); - $this->useContext('parser_result_subcontext_alias', new ParserResultContext()); - $this->useContext('utils_subcontext_alias', new UtilsContext()); - } - -} \ No newline at end of file diff --git a/features/bootstrap/ParserResultContext.php b/features/bootstrap/ParserResultContext.php deleted file mode 100644 index 1b584a4..0000000 --- a/features/bootstrap/ParserResultContext.php +++ /dev/null @@ -1,84 +0,0 @@ -getHash() as $row) { - $result = new ParserResult(); - $file = $row['test-file']; - $result->setResult($file, $row['result']); - if ($row['examples']) { - foreach (explode(', ', $row['examples']) as $example) { - $result->addExample($file, $example); - } - } - -// $result->addWarning($file, $row['warning'] ? explode(', ', $row['warning']) : []); - if ($row['warning']) { - foreach (explode(', ', $row['warning']) as $warning) { - $result->addWarning($file, $warning); - } - } - - if ($row['skip']) { - $result->addSkipped($file); - } - - if (isset($this->results[$file])) { - $this->results[$file]->mergeWithResult($result); - } else { - $this->results[$file] = $result; - } - } - } - - /** - * @Then /^after merging them I\'m expecting one result with:$/ - */ - public function afterMergingThemIMExpectingOneResultWith(TableNode $table) - { - $result = new ParserResult(); - foreach ($this->results as $r) { - $result->mergeWithResult($r); - } - - $warningsCount = $examplesCount = 0; - foreach ($table->getHash() as $row) { - $file = $row['test-file']; - - $warningsCount += count(explode(', ', $row['warning'])); - $examplesCount += count(explode(', ', $row['examples'])); - - assertEquals(explode(', ', $row['warning']), $result->getWarnings($file)); - assertEquals(explode(', ', $row['examples']), $result->getExamples($file)); - assertEquals($row['result'], $result->getResult($file)); - if ($row['skip']) { - assertTrue($result->isSkipped($file)); - } else { - assertFalse($result->isSkipped($file)); - } - } - - assertEquals($warningsCount, $result->countAllWarnings()); - assertEquals($examplesCount, $result->countAllExamples()); - } - -} \ No newline at end of file diff --git a/features/parser-result.feature b/features/parser-result.feature deleted file mode 100644 index c1a585f..0000000 --- a/features/parser-result.feature +++ /dev/null @@ -1,16 +0,0 @@ -Feature: ParserResult - In order to work with parser - As a developer - I need to merge multiple parser results - - Scenario: - When I have multiple parser results like: - | test-file | warning | skip | result | examples | - | file1 | msg1 | | res1 | ex1, ex2 | - | file2 | msg2, msg3 | 1 | res2 | ex4 | - | file1 | | | res1 | ex3 | - | file2 | msg4 | | res4 | | - Then after merging them I'm expecting one result with: - | test-file | warning | skip | result | examples | - | file1 | msg1 | | res1 | ex1, ex2, ex3 | - | file2 | msg2, msg3, msg4 | 1 | res4 | ex4 | \ No newline at end of file diff --git a/features/test-manual-files/datetime.setdate.html b/features/test-manual-files/datetime.setdate.html deleted file mode 100644 index 8fd7563..0000000 --- a/features/test-manual-files/datetime.setdate.html +++ /dev/null @@ -1,192 +0,0 @@ - - - - - Sets the date - - -
-
-

DateTime::setDate

-

date_date_set

-

(PHP 5 >= 5.2.0)

DateTime::setDate -- date_date_setSets the date

- -
- -
-

Description

-

Object oriented style

-
- public DateTime DateTime::setDate - ( int $year - , int $month - , int $day - )
- -

Procedural style

-
- DateTime date_date_set - ( DateTime $object - , int $year - , int $month - , int $day - )
- -

- Resets the current date of the DateTime object to a different date. -

-
- - -
-

Parameters

-
- -
-object
- -
-

Procedural style only: A DateTime object -returned by date_create(). -The function modifies this object.

- - -
-year
- -
- -

- Year of the date. -

-
- - - -
-month
- -
- -

- Month of the date. -

-
- - - -
-day
- -
- -

- Day of the date. -

-
- - -
- -
- - -
-

Return Values

-

- Returns the DateTime object for method chaining or FALSE on failure. -

-
- - -
-

Changelog

- - - - - - - - - - - - - - - -
VersionDescription
5.3.0Changed the -return value on success from NULL to DateTime.
- -
- - -
-

Examples

-
-

Example #1 DateTime::setDate() example

-

Object oriented style

-
-
-<?php
$date 
= new DateTime();
$date->setDate(200123);
echo 
$date->format('Y-m-d');
?> -
-
-
- -

Procedural style

-
-
-<?php
$date 
date_create();
date_date_set($date200123);
echo 
date_format($date'Y-m-d');
?> -
-
-
- -

The above examples will output:

-
-
-2001-02-03
-
-
-
-
-

Example #2 Values exceeding ranges are added to their parent values

-
-
-<?php
$date 
= new DateTime();

$date->setDate(2001228);
echo 
$date->format('Y-m-d') . "\n";

$date->setDate(2001229);
echo 
$date->format('Y-m-d') . "\n";

$date->setDate(2001143);
echo 
$date->format('Y-m-d') . "\n";
?> -
-
-
- -

The above example will output:

-
-
-2001-02-28
-2001-03-01
-2002-02-03
-
-
-
-
- - -
-

See Also

- -
- - -

diff --git a/features/test-manual-files/datetime.setdate.json b/features/test-manual-files/datetime.setdate.json deleted file mode 100644 index 0dfb2c2..0000000 --- a/features/test-manual-files/datetime.setdate.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "desc": "Sets the date.", - "long_desc": "Resets the current date of the DateTime object to a different date.", - "ver": "PHP 5 >= 5.2.0", - "ret_desc": "Returns the DateTime object for method chaining or FALSE on failure.", - "seealso": [ - "DateTime::setISODate", - "DateTime::setTime" - ], - "filename": "datetime.setdate", - "params": [ - { - "list": [ - { - "type": "int", - "var": "$year", - "beh": "required", - "desc": "Year of the date." - }, - { - "type": "int", - "var": "$month", - "beh": "required", - "desc": "Month of the date." - }, - { - "type": "int", - "var": "$day", - "beh": "required", - "desc": "Day of the date." - } - ], - "name": "DateTime::setDate", - "ret_type": "DateTime" - }, - { - "list": [ - { - "type": "DateTime", - "var": "$object", - "beh": "required", - "desc": "Procedural style only: A DateTime object returned by date\\_create(). The function modifies this object." - }, - { - "type": "int", - "var": "$year", - "beh": "required", - "desc": "Year of the date." - }, - { - "type": "int", - "var": "$month", - "beh": "required", - "desc": "Month of the date." - }, - { - "type": "int", - "var": "$day", - "beh": "required", - "desc": "Day of the date." - } - ], - "name": "date_date_set", - "ret_type": "DateTime" - } - ], - "examples": [ - { - "title": "DateTime::setDate() example", - "source": "$date = new DateTime();\n$date->setDate(2001, 2, 3);\necho $date->format('Y-m-d');", - "output": "2001-02-03" - }, - { - "title": "Values exceeding ranges are added to their parent values", - "source": "$date = new DateTime();\n\n$date->setDate(2001, 2, 28);\necho $date->format('Y-m-d') . \"\\n\";\n\n$date->setDate(2001, 2, 29);\necho $date->format('Y-m-d') . \"\\n\";\n\n$date->setDate(2001, 14, 3);\necho $date->format('Y-m-d') . \"\\n\";", - "output": "2001-02-28\n2001-03-01\n2002-02-03" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/eventhttp.setcallback.html b/features/test-manual-files/eventhttp.setcallback.html deleted file mode 100644 index db2940b..0000000 --- a/features/test-manual-files/eventhttp.setcallback.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Sets a callback for specified URI - - -
-
-

EventHttp::setCallback

-

(PECL event >= 1.4.0-beta)

EventHttp::setCallbackSets a callback for specified URI

- -
-
-

Description

-
- public - void - EventHttp::setCallback - ( - string - $path - - , - string - $cb - - [, - string - $arg - - ] )
- -

- Sets a callback for specified URI. -

-
- -
-

Parameters

-
- - -
- - path -
- -
- -

- The path for which to invoke the callback. -

-
- - - -
- - cb -
- -
- -

- The callback - callable - that gets invoked on requested - path - . It should match the following prototype: -

-
- void - callback - ([ - EventHttpRequest - $req - = NULL - - [, - mixed - $arg - = NULL - - ]] )
- -

-

- - -
- - req -
- -
- -

- EventHttpRequest - object. -

-
- - - -
- - arg -
- -
- -

- Custom data. -

-
- - -
- -

-
- - - -
- - arg -
- -
- -

- Custom data. -

-
- - -
- -
- -
-

Return Values

-

- Returns TRUE on success. Otherwise FALSE. -

-
- -
-

Examples

-
-

Example #1 - EventHttp::setCallback() example

-
-
-<?php
/*
 * Simple HTTP server.
 *
 * To test it:
 * 1) Run it on a port of your choice, e.g.:
 * $ php examples/http.php 8010
 * 2) In another terminal connect to some address on this port
 * and make GET or POST request(others are turned off here), e.g.:
 * $ nc -t 127.0.0.1 8010
 * POST /about HTTP/1.0
 * Content-Type: text/plain
 * Content-Length: 4
 * Connection: close
 * (press Enter)
 *
 * It will output
 * a=12
 * HTTP/1.0 200 OK
 * Content-Type: text/html; charset=ISO-8859-1
 * Connection: close
 *
 * 3) See what the server outputs on the previous terminal window.
 */

function _http_dump($req$data) {
    static 
$counter      0;
    static 
$max_requests 2;

    if (++
$counter >= $max_requests)  {
        echo 
"Counter reached max requests $max_requests. Exiting\n";
        exit();
    }

    echo 
__METHOD__" called\n";
    echo 
"request:"var_dump($req);
    echo 
"data:"var_dump($data);

    echo 
"\n===== DUMP =====\n";
    echo 
"Command:"$req->getCommand(), PHP_EOL;
    echo 
"URI:"$req->getUri(), PHP_EOL;
    echo 
"Input headers:"var_dump($req->getInputHeaders());
    echo 
"Output headers:"var_dump($req->getOutputHeaders());

    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";

    echo 
"\n >> Reading input buffer ...\n";
    
$buf $req->getInputBuffer();
    while (
$s $buf->readLine(EventBuffer::EOL_ANY)) {
        echo 
$sPHP_EOL;
    }
    echo 
"No more data in the buffer\n";
}

function 
_http_about($req) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

function 
_http_default($req$data) {
    echo 
__METHOD__PHP_EOL;
    echo 
"URI: "$req->getUri(), PHP_EOL;
    echo 
"\n >> Sending reply ...";
    
$req->sendReply(200"OK");
    echo 
"OK\n";
}

$port 8010;
if (
$argc 1) {
    
$port = (int) $argv[1];
}
if (
$port <= || $port 65535) {
    exit(
"Invalid port");
}

$base = new EventBase();
$http = new EventHttp($base);
$http->setAllowedMethods(EventHttpRequest::CMD_GET EventHttpRequest::CMD_POST);

$http->setCallback("/dump""_http_dump", array(48));
$http->setCallback("/about""_http_about");
$http->setDefaultCallback("_http_default""custom data value");

$http->bind("0.0.0.0"8010);
$base->loop();
?> -
-
-
- -

The above example will output -something similar to:

-
-
-a=12
-HTTP/1.0 200 OK
-Content-Type: text/html; charset=ISO-8859-1
-Connection: close
-
-
-
-
- -
-

See Also

- -
- -

diff --git a/features/test-manual-files/eventhttp.setcallback.json b/features/test-manual-files/eventhttp.setcallback.json deleted file mode 100644 index e57d52a..0000000 --- a/features/test-manual-files/eventhttp.setcallback.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "desc": "Sets a callback for specified URI.", - "long_desc": "Sets a callback for specified URI.", - "ver": "PECL event >= 1.4.0-beta", - "ret_desc": "Returns TRUE on success. Otherwise FALSE.", - "seealso": [ - "EventHttp::setDefaultCallback" - ], - "filename": "eventhttp.setcallback", - "params": [ - { - "list": [ - { - "type": "string", - "var": "$path", - "beh": "required", - "desc": "The path for which to invoke the callback." - }, - { - "type": "string", - "var": "$cb", - "beh": "required", - "desc": "The callback callable that gets invoked on requested `path` . It should match the following prototype:\\n\\nvoid callback ([ EventHttpRequest `$req` = NULL [, mixed `$arg` = NULL ]] )" - }, - { - "type": "string", - "var": "$arg", - "beh": "optional", - "desc": "Custom data." - } - ], - "name": "EventHttp::setCallback", - "ret_type": "void" - } - ], - "examples": [ - { - "title": "EventHttp::setCallback() example", - "source": "\/*\n * Simple HTTP server.\n *\n * To test it:\n * 1) Run it on a port of your choice, e.g.:\n * $ php examples\/http.php 8010\n * 2) In another terminal connect to some address on this port\n * and make GET or POST request(others are turned off here), e.g.:\n * $ nc -t 127.0.0.1 8010\n * POST \/about HTTP\/1.0\n * Content-Type: text\/plain\n * Content-Length: 4\n * Connection: close\n * (press Enter)\n *\n * It will output\n * a=12\n * HTTP\/1.0 200 OK\n * Content-Type: text\/html; charset=ISO-8859-1\n * Connection: close\n *\n * 3) See what the server outputs on the previous terminal window.\n *\/\n\nfunction _http_dump($req, $data) {\n static $counter = 0;\n static $max_requests = 2;\n\n if (++$counter >= $max_requests) {\n echo \"Counter reached max requests $max_requests. Exiting\\n\";\n exit();\n }\n\n echo __METHOD__, \" called\\n\";\n echo \"request:\"; var_dump($req);\n echo \"data:\"; var_dump($data);\n\n echo \"\\n===== DUMP =====\\n\";\n echo \"Command:\", $req->getCommand(), PHP_EOL;\n echo \"URI:\", $req->getUri(), PHP_EOL;\n echo \"Input headers:\"; var_dump($req->getInputHeaders());\n echo \"Output headers:\"; var_dump($req->getOutputHeaders());\n\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n\n echo \"\\n >> Reading input buffer ...\\n\";\n $buf = $req->getInputBuffer();\n while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {\n echo $s, PHP_EOL;\n }\n echo \"No more data in the buffer\\n\";\n}\n\nfunction _http_about($req) {\n echo __METHOD__, PHP_EOL;\n echo \"URI: \", $req->getUri(), PHP_EOL;\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n}\n\nfunction _http_default($req, $data) {\n echo __METHOD__, PHP_EOL;\n echo \"URI: \", $req->getUri(), PHP_EOL;\n echo \"\\n >> Sending reply ...\";\n $req->sendReply(200, \"OK\");\n echo \"OK\\n\";\n}\n\n$port = 8010;\nif ($argc > 1) {\n $port = (int) $argv[1];\n}\nif ($port <= 0 || $port > 65535) {\n exit(\"Invalid port\");\n}\n\n$base = new EventBase();\n$http = new EventHttp($base);\n$http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);\n\n$http->setCallback(\"\/dump\", \"_http_dump\", array(4, 8));\n$http->setCallback(\"\/about\", \"_http_about\");\n$http->setDefaultCallback(\"_http_default\", \"custom data value\");\n\n$http->bind(\"0.0.0.0\", 8010);\n$base->loop();", - "output": "a=12\nHTTP\/1.0 200 OK\nContent-Type: text\/html; charset=ISO-8859-1\nConnection: close" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/function.array-diff.html b/features/test-manual-files/function.array-diff.html deleted file mode 100644 index 786b5dd..0000000 --- a/features/test-manual-files/function.array-diff.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - Computes the difference of arrays - - -
-
-

array_diff

-

(PHP 4 >= 4.0.1, PHP 5)

array_diffComputes the difference of arrays

- -
- -
-

Description

-
- array array_diff - ( array $array1 - , array $array2 - [, array $... - ] )
- -

- Compares array1 against one or more other arrays and - returns the values in array1 that are not present in - any of the other arrays. -

-
- - -
-

Parameters

-

-

- - -
-array1
- -
- -

- The array to compare from -

-
- - - -
-array2
- -
- -

- An array to compare against -

-
- - - -
-...
- -
- -

- More arrays to compare against -

-
- - -
- -

-
- - -
-

Return Values

-

- Returns an array containing all the entries from - array1 that are not present in any of the other arrays. -

-
- - -
-

Examples

-

-

-

Example #1 array_diff() example

-
-
-<?php
$array1 
= array("a" => "green""red""blue""red");
$array2 = array("b" => "green""yellow""red");
$result array_diff($array1$array2);

print_r($result);
?> -
-
-
- -

- Multiple occurrences in $array1 are all - treated the same way. This will output : -

-
-
-Array
-(
-    [1] => blue
-)
-
-
-
-

-
- - -
-

Notes

-

Note: -

- Two elements are considered equal if and only if - (string) $elem1 === (string) $elem2. In words: - when the string representation is the same. - -

-

-

Note: -

- This function only checks one dimension of a n-dimensional - array. Of course you can check deeper dimensions by using - array_diff($array1[0], $array2[0]);. -

-

-
- - -
-

See Also

-

-

-

-
- - -

diff --git a/features/test-manual-files/function.array-diff.json b/features/test-manual-files/function.array-diff.json deleted file mode 100644 index 0aa300f..0000000 --- a/features/test-manual-files/function.array-diff.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "desc": "Computes the difference of arrays.", - "long_desc": "Compares `array1` against one or more other arrays and returns the values in `array1` that are not present in any of the other arrays.", - "ver": "PHP 4 >= 4.0.1, PHP 5", - "ret_desc": "Returns an array containing all the entries from array1 that are not present in any of the other arrays.", - "seealso": [ - "array_diff_assoc", - "array_intersect", - "array_intersect_assoc" - ], - "filename": "function.array-diff", - "params": [ - { - "name": "array_diff", - "list": [ - { - "type": "array", - "var": "$array1", - "beh": "required", - "desc": "The array to compare from" - }, - { - "type": "array", - "var": "$array2", - "beh": "required", - "desc": "An array to compare against" - }, - { - "type": "array", - "var": "$...", - "beh": "optional", - "desc": "More arrays to compare against" - } - ], - "ret_type": "array" - } - ], - "examples": [ - { - "title": "array_diff() example", - "source": "$array1 = array(\"a\" => \"green\", \"red\", \"blue\", \"red\");\n$array2 = array(\"b\" => \"green\", \"yellow\", \"red\");\n$result = array_diff($array1, $array2);\n\nprint_r($result);", - "output": "Array\n(\n [1] => blue\n)" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/function.chown.html b/features/test-manual-files/function.chown.html deleted file mode 100644 index adfdfed..0000000 --- a/features/test-manual-files/function.chown.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - Changes file owner - - -
-
-

chown

-

(PHP 4, PHP 5)

chownChanges file owner

- -
- -
-

Description

-
- bool chown - ( string $filename - , mixed $user - )
- -

- Attempts to change the owner of the file filename - to user user. Only the superuser may change the - owner of a file. -

-
- - -
-

Parameters

-

-

- - -
-filename
- -
- -

- Path to the file. -

-
- - - -
-user
- -
- -

- A user name or number. -

-
- - -
- -

-
- - -
-

Return Values

-

- Returns TRUE on success or FALSE on failure. -

-
- - -
-

Examples

-

-

-

Example #1 Simple chown() usage

-
-
-<?php

// File name and username to use
$file_name"foo.php";
$path "/home/sites/php.net/public_html/sandbox/" $file_name ;
$user_name "root";

// Set the user
chown($path$user_name);

// Check the result
$stat stat($path);
print_r(posix_getpwuid($stat['uid']));

?> -
-
-
- -

The above example will output -something similar to:

-
-
-Array
-(
-    [name] => root
-    [passwd] => x
-    [uid] => 0
-    [gid] => 0
-    [gecos] => root
-    [dir] => /root
-    [shell] => /bin/bash
-)
-
-
-
-

-
- - -
-

Notes

-

Note: This function will not work on -remote files as the file to -be examined must be accessible via the server's filesystem.

-

Note: When safe mode is enabled, PHP checks whether -the files or directories being operated upon have the same UID (owner) as the -script that is being executed.

-
- - -
-

See Also

-

-

-

-
- - -

diff --git a/features/test-manual-files/function.chown.json b/features/test-manual-files/function.chown.json deleted file mode 100644 index 221d081..0000000 --- a/features/test-manual-files/function.chown.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "desc": "Changes file owner.", - "long_desc": "Attempts to change the owner of the file `filename` to user `user`. Only the superuser may change the owner of a file.", - "ver": "PHP 4, PHP 5", - "ret_desc": "Returns TRUE on success or FALSE on failure.", - "seealso": [ - "chmod", "chgrp" - ], - "filename": "function.chown", - "params": [ - { - "name": "chown", - "list": [ - { - "type": "string", - "var": "$filename", - "beh": "required", - "desc": "Path to the file." - }, - { - "type": "mixed", - "var": "$user", - "beh": "required", - "desc": "A user name or number." - } - ], - "ret_type": "bool" - } - ], - "examples": [ - { - "title": "Simple chown() usage", - "source": "\/\/ File name and username to use\n$file_name= \"foo.php\";\n$path = \"\/home\/sites\/php.net\/public_html\/sandbox\/\" . $file_name ;\n$user_name = \"root\";\n\n\/\/ Set the user\nchown($path, $user_name);\n\n\/\/ Check the result\n$stat = stat($path);\nprint_r(posix_getpwuid($stat['uid']));", - "output": "Array\n(\n [name] => root\n [passwd] => x\n [uid] => 0\n [gid] => 0\n [gecos] => root\n [dir] => \/root\n [shell] => \/bin\/bash\n)" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/function.json-encode.html b/features/test-manual-files/function.json-encode.html deleted file mode 100644 index 7e9375d..0000000 --- a/features/test-manual-files/function.json-encode.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Returns the JSON representation of a value - - -
-
-

json_encode

-

(PHP 5 >= 5.2.0, PECL json >= 1.2.0)

json_encodeReturns the JSON representation of a value

- -
- -
-

Description

-
- string json_encode - ( mixed $value - [, int $options = 0 - [, int $depth = 512 - ]] )
- -

- Returns a string containing the JSON representation of - value. -

-
- - -
-

Parameters

-

-

- - -
-value
- -
- -

- The value being encoded. Can be any type except - a resource. -

-

- All string data must be UTF-8 encoded. -

- -

Note: -

- PHP implements a superset of JSON as specified in the original - » RFC 4627 - it will also encode and - decode scalar types and NULL. RFC 4627 only supports these values when - they are nested inside an array or an object. -

-

- Although this superset is consistent with the expanded definition of "JSON - text" in the newer » RFC 7159 (which - aims to supersede RFC 4627) and - » ECMA-404, this may cause - interoperability issues with older JSON parsers that adhere strictly to RFC - 4627 when encoding a single scalar value. -

-

- -
- - - -
-options
- -
- -

- Bitmask consisting of JSON_HEX_QUOT, - JSON_HEX_TAG, - JSON_HEX_AMP, - JSON_HEX_APOS, - JSON_NUMERIC_CHECK, - JSON_PRETTY_PRINT, - JSON_UNESCAPED_SLASHES, - JSON_FORCE_OBJECT, - JSON_PRESERVE_ZERO_FRACTION, - JSON_UNESCAPED_UNICODE. The behaviour of these - constants is described on the - JSON constants page. -

-
- - - -
-depth
- -
- -

- Set the maximum depth. Must be greater than zero. -

-
- - -
- -

-
- - -
-

Return Values

-

- Returns a JSON encoded string on success or FALSE on failure. -

-
- - -
-

Changelog

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VersionDescription
5.6.6 - JSON_PRESERVE_ZERO_FRACTION option was added. -
5.5.0 - depth parameter was added. -
5.4.0 - JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, and JSON_UNESCAPED_UNICODE options were added. -
5.3.3 - JSON_NUMERIC_CHECK option was added. -
5.3.0 - The options parameter was added. -
- -

-
- - -
-

Examples

-

-

-

Example #1 A json_encode() example

-
-
-<?php
$arr 
= array('a' => 1'b' => 2'c' => 3'd' => 4'e' => 5);

echo 
json_encode($arr);
?> -
-
-
- -

The above example will output:

-
-
-{"a":1,"b":2,"c":3,"d":4,"e":5}
-
-
-
- -
-

Example #2 - A json_encode() example showing some options in use -

-
-
-<?php
$a 
= array('<foo>',"'bar'",'"baz"','&blong&'"\xc3\xa9");

echo 
"Normal: ",  json_encode($a), "\n";
echo 
"Tags: ",    json_encode($aJSON_HEX_TAG), "\n";
echo 
"Apos: ",    json_encode($aJSON_HEX_APOS), "\n";
echo 
"Quot: ",    json_encode($aJSON_HEX_QUOT), "\n";
echo 
"Amp: ",     json_encode($aJSON_HEX_AMP), "\n";
echo 
"Unicode: "json_encode($aJSON_UNESCAPED_UNICODE), "\n";
echo 
"All: ",     json_encode($aJSON_HEX_TAG JSON_HEX_APOS JSON_HEX_QUOT JSON_HEX_AMP JSON_UNESCAPED_UNICODE), "\n\n";

$b = array();

echo 
"Empty array output as array: "json_encode($b), "\n";
echo 
"Empty array output as object: "json_encode($bJSON_FORCE_OBJECT), "\n\n";

$c = array(array(1,2,3));

echo 
"Non-associative array output as array: "json_encode($c), "\n";
echo 
"Non-associative array output as object: "json_encode($cJSON_FORCE_OBJECT), "\n\n";

$d = array('foo' => 'bar''baz' => 'long');

echo 
"Associative array always output as object: "json_encode($d), "\n";
echo 
"Associative array always output as object: "json_encode($dJSON_FORCE_OBJECT), "\n\n";
?> -
-
-
- -

The above example will output:

-
-
-Normal: ["<foo>","'bar'","\"baz\"","&blong&","\u00e9"]
-Tags: ["\u003Cfoo\u003E","'bar'","\"baz\"","&blong&","\u00e9"]
-Apos: ["<foo>","\u0027bar\u0027","\"baz\"","&blong&","\u00e9"]
-Quot: ["<foo>","'bar'","\u0022baz\u0022","&blong&","\u00e9"]
-Amp: ["<foo>","'bar'","\"baz\"","\u0026blong\u0026","\u00e9"]
-Unicode: ["<foo>","'bar'","\"baz\"","&blong&","Ă©"]
-All: ["\u003Cfoo\u003E","\u0027bar\u0027","\u0022baz\u0022","\u0026blong\u0026","Ă©"]
-
-Empty array output as array: []
-Empty array output as object: {}
-
-Non-associative array output as array: [[1,2,3]]
-Non-associative array output as object: {"0":{"0":1,"1":2,"2":3}}
-
-Associative array always output as object: {"foo":"bar","baz":"long"}
-Associative array always output as object: {"foo":"bar","baz":"long"}
-
-
-
-
-

Example #3 JSON_NUMERIC_CHECK option example

-
-
-<?php
echo "Strings representing numbers automatically turned into numbers".PHP_EOL;
$numbers = array('+123123''-123123''1.2e3''0.00001');
var_dump(
 
$numbers,
 
json_encode($numbersJSON_NUMERIC_CHECK)
);
echo 
"Strings containing improperly formatted numbers".PHP_EOL;
$strings = array('+a33123456789''a123');
var_dump(
 
$strings,
 
json_encode($stringsJSON_NUMERIC_CHECK)
);
?> -
-
-
- -

The above example will output:

-
-
-Strings representing numbers automatically turned into numbers
-array(4) {
-  [0]=>
-  string(7) "+123123"
-  [1]=>
-  string(7) "-123123"
-  [2]=>
-  string(5) "1.2e3"
-  [3]=>
-  string(7) "0.00001"
-}
-string(28) "[123123,-123123,1200,1.0e-5]"
-Strings containing improperly formatted numbers
-array(2) {
-  [0]=>
-  string(13) "+a33123456789"
-  [1]=>
-  string(4) "a123"
-}
-string(24) "["+a33123456789","a123"]"
-
-
-
-
-

Example #4 Sequential versus non-sequential array example

-
-
-<?php
echo "Sequential array".PHP_EOL;
$sequential = array("foo""bar""baz""blong");
var_dump(
 
$sequential,
 
json_encode($sequential)
);

echo 
PHP_EOL."Non-sequential array".PHP_EOL;
$nonsequential = array(1=>"foo"2=>"bar"3=>"baz"4=>"blong");
var_dump(
 
$nonsequential,
 
json_encode($nonsequential)
);

echo 
PHP_EOL."Sequential array with one key unset".PHP_EOL;
unset(
$sequential[1]);
var_dump(
 
$sequential,
 
json_encode($sequential)
);
?> -
-
-
- -

The above example will output:

-
-
-Sequential array
-array(4) {
-  [0]=>
-  string(3) "foo"
-  [1]=>
-  string(3) "bar"
-  [2]=>
-  string(3) "baz"
-  [3]=>
-  string(5) "blong"
-}
-string(27) "["foo","bar","baz","blong"]"
-
-Non-sequential array
-array(4) {
-  [1]=>
-  string(3) "foo"
-  [2]=>
-  string(3) "bar"
-  [3]=>
-  string(3) "baz"
-  [4]=>
-  string(5) "blong"
-}
-string(43) "{"1":"foo","2":"bar","3":"baz","4":"blong"}"
-
-Sequential array with one key unset
-array(3) {
-  [0]=>
-  string(3) "foo"
-  [2]=>
-  string(3) "baz"
-  [3]=>
-  string(5) "blong"
-}
-string(33) "{"0":"foo","2":"baz","3":"blong"}"
-
-
-
-
-

Example #5 JSON_PRESERVE_ZERO_FRACTION option example

-
-
-<?php
var_dump
(json_encode(12.0JSON_PRESERVE_ZERO_FRACTION));
var_dump(json_encode(12.0));
?> -
-
-
- -

The above example will output:

-
-
-string(4) "12.0"
-string(2) "12"
-
-
-
-

-
- - -
-

Notes

-

Note: -

- In the event of a failure to encode, json_last_error() - can be used to determine the exact nature of the error. -

-

-

Note: -

- When encoding an array, if the keys are not a continuous numeric - sequence starting from 0, all keys are encoded as strings, and - specified explicitly for each key-value pair. -

-

-

Note: -

- Like the reference JSON encoder, json_encode() will - generate JSON that is a simple value (that is, neither an object nor an - array) if given a string, integer, - float or boolean as an input - value. While most decoders will accept these values - as valid JSON, some may not, as the specification is ambiguous on this - point. -

-

- To summarise, always test that your JSON decoder can handle the output you - generate from json_encode(). -

-

-
- - -
-

See Also

-

-

-

-
- -

diff --git a/features/test-manual-files/function.json-encode.json b/features/test-manual-files/function.json-encode.json deleted file mode 100644 index 6614533..0000000 --- a/features/test-manual-files/function.json-encode.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "desc": "Returns the JSON representation of a value.", - "long_desc": "Returns a string containing the JSON representation of `value`.", - "ver": "PHP 5 >= 5.2.0, PECL json >= 1.2.0", - "ret_desc": "Returns a JSON encoded string on success or FALSE on failure.", - "seealso": [ - "JsonSerializable", "json_decode", "json_last_error", "serialize" - ], - "filename": "function.json-encode", - "params": [ - { - "name": "json_encode", - "list": [ - { - "type": "mixed", - "var": "$value", - "beh": "required", - "desc": "The `value` being encoded. Can be any type except a resource.\\n\\nAll string data must be UTF-8 encoded.\\n\\n**Note**: PHP implements a superset of JSON as specified in the original \u00bb\u00a0RFC 4627 - it will also encode and decode scalar types and `NULL`. RFC 4627 only supports these values when they are nested inside an array or an object. Although this superset is consistent with the expanded definition of \"JSON text\" in the newer \u00bb\u00a0RFC 7159 (which aims to supersede RFC 4627) and \u00bb\u00a0ECMA-404, this may cause interoperability issues with older JSON parsers that adhere strictly to RFC 4627 when encoding a single scalar value." - }, - { - "type": "int", - "var": "$options", - "beh": "optional", - "desc": "Bitmask consisting of `JSON_HEX_QUOT`, `JSON_HEX_TAG`, `JSON_HEX_AMP`, `JSON_HEX_APOS`, `JSON_NUMERIC_CHECK`, `JSON_PRETTY_PRINT`, `JSON_UNESCAPED_SLASHES`, `JSON_FORCE_OBJECT`, `JSON_PRESERVE_ZERO_FRACTION`, `JSON_UNESCAPED_UNICODE`. The behaviour of these constants is described on the JSON constants page.", - "default": 0 - }, - { - "type": "int", - "var": "$depth", - "beh": "optional", - "desc": "Set the maximum depth. Must be greater than zero.", - "default": 512 - } - ], - "ret_type": "string" - } - ], - "examples": [ - { - "title": "A json_encode() example", - "source": "$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);\n\necho json_encode($arr);", - "output": "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}" - }, - { - "title": "A json_encode() example showing some options in use", - "source": "$a = array('',\"'bar'\",'\"baz\"','&blong&', \"\\xc3\\xa9\");\n\necho \"Normal: \", json_encode($a), \"\\n\";\necho \"Tags: \", json_encode($a, JSON_HEX_TAG), \"\\n\";\necho \"Apos: \", json_encode($a, JSON_HEX_APOS), \"\\n\";\necho \"Quot: \", json_encode($a, JSON_HEX_QUOT), \"\\n\";\necho \"Amp: \", json_encode($a, JSON_HEX_AMP), \"\\n\";\necho \"Unicode: \", json_encode($a, JSON_UNESCAPED_UNICODE), \"\\n\";\necho \"All: \", json_encode($a, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE), \"\\n\\n\";\n\n$b = array();\n\necho \"Empty array output as array: \", json_encode($b), \"\\n\";\necho \"Empty array output as object: \", json_encode($b, JSON_FORCE_OBJECT), \"\\n\\n\";\n\n$c = array(array(1,2,3));\n\necho \"Non-associative array output as array: \", json_encode($c), \"\\n\";\necho \"Non-associative array output as object: \", json_encode($c, JSON_FORCE_OBJECT), \"\\n\\n\";\n\n$d = array('foo' => 'bar', 'baz' => 'long');\n\necho \"Associative array always output as object: \", json_encode($d), \"\\n\";\necho \"Associative array always output as object: \", json_encode($d, JSON_FORCE_OBJECT), \"\\n\\n\";", - "output": "Normal: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nTags: [\"\\u003Cfoo\\u003E\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nApos: [\"\",\"\\u0027bar\\u0027\",\"\\\"baz\\\"\",\"&blong&\",\"\\u00e9\"]\nQuot: [\"\",\"'bar'\",\"\\u0022baz\\u0022\",\"&blong&\",\"\\u00e9\"]\nAmp: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"\\u0026blong\\u0026\",\"\\u00e9\"]\nUnicode: [\"\",\"'bar'\",\"\\\"baz\\\"\",\"&blong&\",\"\u00e9\"]\nAll: [\"\\u003Cfoo\\u003E\",\"\\u0027bar\\u0027\",\"\\u0022baz\\u0022\",\"\\u0026blong\\u0026\",\"\u00e9\"]\n\nEmpty array output as array: []\nEmpty array output as object: {}\n\nNon-associative array output as array: [[1,2,3]]\nNon-associative array output as object: {\"0\":{\"0\":1,\"1\":2,\"2\":3}}\n\nAssociative array always output as object: {\"foo\":\"bar\",\"baz\":\"long\"}\nAssociative array always output as object: {\"foo\":\"bar\",\"baz\":\"long\"}" - }, - { - "title": "JSON_NUMERIC_CHECK option example", - "source": "echo \"Strings representing numbers automatically turned into numbers\".PHP_EOL;\n$numbers = array('+123123', '-123123', '1.2e3', '0.00001');\nvar_dump(\n $numbers,\n json_encode($numbers, JSON_NUMERIC_CHECK)\n);\necho \"Strings containing improperly formatted numbers\".PHP_EOL;\n$strings = array('+a33123456789', 'a123');\nvar_dump(\n $strings,\n json_encode($strings, JSON_NUMERIC_CHECK)\n);", - "output": "Strings representing numbers automatically turned into numbers\narray(4) {\n [0]=>\n string(7) \"+123123\"\n [1]=>\n string(7) \"-123123\"\n [2]=>\n string(5) \"1.2e3\"\n [3]=>\n string(7) \"0.00001\"\n}\nstring(28) \"[123123,-123123,1200,1.0e-5]\"\nStrings containing improperly formatted numbers\narray(2) {\n [0]=>\n string(13) \"+a33123456789\"\n [1]=>\n string(4) \"a123\"\n}\nstring(24) \"[\"+a33123456789\",\"a123\"]\"" - }, - { - "title": "Sequential versus non-sequential array example", - "source": "echo \"Sequential array\".PHP_EOL;\n$sequential = array(\"foo\", \"bar\", \"baz\", \"blong\");\nvar_dump(\n $sequential,\n json_encode($sequential)\n);\n\necho PHP_EOL.\"Non-sequential array\".PHP_EOL;\n$nonsequential = array(1=>\"foo\", 2=>\"bar\", 3=>\"baz\", 4=>\"blong\");\nvar_dump(\n $nonsequential,\n json_encode($nonsequential)\n);\n\necho PHP_EOL.\"Sequential array with one key unset\".PHP_EOL;\nunset($sequential[1]);\nvar_dump(\n $sequential,\n json_encode($sequential)\n);", - "output": "Sequential array\narray(4) {\n [0]=>\n string(3) \"foo\"\n [1]=>\n string(3) \"bar\"\n [2]=>\n string(3) \"baz\"\n [3]=>\n string(5) \"blong\"\n}\nstring(27) \"[\"foo\",\"bar\",\"baz\",\"blong\"]\"\n\nNon-sequential array\narray(4) {\n [1]=>\n string(3) \"foo\"\n [2]=>\n string(3) \"bar\"\n [3]=>\n string(3) \"baz\"\n [4]=>\n string(5) \"blong\"\n}\nstring(43) \"{\"1\":\"foo\",\"2\":\"bar\",\"3\":\"baz\",\"4\":\"blong\"}\"\n\nSequential array with one key unset\narray(3) {\n [0]=>\n string(3) \"foo\"\n [2]=>\n string(3) \"baz\"\n [3]=>\n string(5) \"blong\"\n}\nstring(33) \"{\"0\":\"foo\",\"2\":\"baz\",\"3\":\"blong\"}\"" - }, - { - "title": "JSON_PRESERVE_ZERO_FRACTION option example", - "source": "var_dump(json_encode(12.0, JSON_PRESERVE_ZERO_FRACTION));\nvar_dump(json_encode(12.0));", - "output": "string(4) \"12.0\"\nstring(2) \"12\"" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/function.str-replace.html b/features/test-manual-files/function.str-replace.html deleted file mode 100644 index 314e91e..0000000 --- a/features/test-manual-files/function.str-replace.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Replace all occurrences of the search string with the replacement string - - -
-
-

str_replace

-

(PHP 4, PHP 5)

str_replaceReplace all occurrences of the search string with the replacement string

- -
- -
-

Description

-
- mixed str_replace - ( mixed $search - , mixed $replace - , mixed $subject - [, int &$count - ] )
- -

- This function returns a string or an array with all occurrences of - search in subject - replaced with the given replace value. -

-

- If you don't need fancy replacing rules (like regular expressions), you - should always use this function instead of preg_replace(). -

-
- - -
-

Parameters

-

- If search and replace are - arrays, then str_replace() takes a value from each array - and uses them to search and replace on subject. If - replace has fewer values than - search, then an empty string is used for the rest of - replacement values. If search is an array and - replace is a string, then this replacement string is - used for every value of search. The converse would - not make sense, though. -

-

- If search or replace - are arrays, their elements are processed first to last. -

-

-

- - -
-search
- -
- -

- The value being searched for, otherwise known as the needle. - An array may be used to designate multiple needles. -

-
- - - -
-replace
- -
- -

- The replacement value that replaces found search - values. An array may be used to designate multiple replacements. -

-
- - - -
-subject
- -
- -

- The string or array being searched and replaced on, - otherwise known as the haystack. -

-

- If subject is an array, then the search and - replace is performed with every entry of - subject, and the return value is an array as - well. -

-
- - - -
-count
- -
- -

- If passed, this will be set to the number of replacements performed. -

-
- - -
- -

-
- - -
-

Return Values

-

- This function returns a string or an array with the replaced values. -

-
- - -
-

Examples

-

-

-

Example #1 Basic str_replace() examples

-
-
-<?php
// Provides: <body text='black'>
$bodytag str_replace("%body%""black""<body text='%body%'>");

// Provides: Hll Wrld f PHP
$vowels = array("a""e""i""o""u""A""E""I""O""U");
$onlyconsonants str_replace($vowels"""Hello World of PHP");

// Provides: You should eat pizza, beer, and ice cream every day
$phrase  "You should eat fruits, vegetables, and fiber every day.";
$healthy = array("fruits""vegetables""fiber");
$yummy   = array("pizza""beer""ice cream");

$newphrase str_replace($healthy$yummy$phrase);

// Provides: 2
$str str_replace("ll""""good golly miss molly!"$count);
echo 
$count;
?> -
-
-
- -
-

-

-

-

Example #2 Examples of potential str_replace() gotchas

-
-
-<?php
// Order of replacement
$str     "Line 1\nLine 2\rLine 3\r\nLine 4\n";
$order   = array("\r\n""\n""\r");
$replace '<br />';

// Processes \r\n's first so they aren't converted twice.
$newstr str_replace($order$replace$str);

// Outputs F because A is replaced with B, then B is replaced with C, and so on...
// Finally E is replaced with F, because of left to right replacements.
$search  = array('A''B''C''D''E');
$replace = array('B''C''D''E''F');
$subject 'A';
echo 
str_replace($search$replace$subject);

// Outputs: apearpearle pear
// For the same reason mentioned above
$letters = array('a''p');
$fruit   = array('apple''pear');
$text    'a p';
$output  str_replace($letters$fruit$text);
echo 
$output;
?> -
-
-
- -
-

-
- - -
-

Notes

-

Note: This function is -binary-safe.

-
Caution -

Replacement order gotcha

-

- Because str_replace() replaces left to right, it might - replace a previously inserted value when doing multiple replacements. - See also the examples in this document. -

-
-

Note: -

- This function is case-sensitive. Use str_ireplace() - for case-insensitive replace. -

-

-
- - -
-

See Also

-

-

-

-
- - -

diff --git a/features/test-manual-files/function.str-replace.json b/features/test-manual-files/function.str-replace.json deleted file mode 100644 index d942aea..0000000 --- a/features/test-manual-files/function.str-replace.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "desc": "Replace all occurrences of the search string with the replacement string.", - "long_desc": "This function returns a string or an array with all occurrences of `search` in `subject` replaced with the given `replace` value.\\n\\nIf you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg\\_replace().", - "ver": "PHP 4, PHP 5", - "ret_desc": "This function returns a string or an array with the replaced values.", - "seealso": [ - "str_ireplace", - "substr_replace", - "preg_replace", - "strtr" - ], - "filename": "function.str-replace", - "params": [ - { - "name": "str_replace", - "list": [ - { - "type": "mixed", - "var": "$search", - "beh": "required", - "desc": "The value being searched for, otherwise known as the needle`. An array may be used to designate multiple needles." - }, - { - "type": "mixed", - "var": "$replace", - "beh": "required", - "desc": "The replacement value that replaces found `search` values. An array may be used to designate multiple replacements." - }, - { - "type": "mixed", - "var": "$subject", - "beh": "required", - "desc": "The string or array being searched and replaced on, otherwise known as the haystack`.\\n\\nIf `subject` is an array, then the search and replace is performed with every entry of `subject`, and the return value is an array as well." - }, - { - "type": "int", - "var": "&$count", - "beh": "optional", - "desc": "If passed, this will be set to the number of replacements performed." - } - ], - "ret_type": "mixed" - } - ], - "examples": [ - { - "title": "Basic str_replace() examples", - "source": "\/\/ Provides: \n$bodytag = str_replace(\"%body%\", \"black\", \"\");\n\n\/\/ Provides: Hll Wrld f PHP\n$vowels = array(\"a\", \"e\", \"i\", \"o\", \"u\", \"A\", \"E\", \"I\", \"O\", \"U\");\n$onlyconsonants = str_replace($vowels, \"\", \"Hello World of PHP\");\n\n\/\/ Provides: You should eat pizza, beer, and ice cream every day\n$phrase = \"You should eat fruits, vegetables, and fiber every day.\";\n$healthy = array(\"fruits\", \"vegetables\", \"fiber\");\n$yummy = array(\"pizza\", \"beer\", \"ice cream\");\n\n$newphrase = str_replace($healthy, $yummy, $phrase);\n\n\/\/ Provides: 2\n$str = str_replace(\"ll\", \"\", \"good golly miss molly!\", $count);\necho $count;", - "output": null - }, - { - "title": "Examples of potential str_replace() gotchas", - "source": "\/\/ Order of replacement\n$str = \"Line 1\\nLine 2\\rLine 3\\r\\nLine 4\\n\";\n$order = array(\"\\r\\n\", \"\\n\", \"\\r\");\n$replace = '
';\n\n\/\/ Processes \\r\\n's first so they aren't converted twice.\n$newstr = str_replace($order, $replace, $str);\n\n\/\/ Outputs F because A is replaced with B, then B is replaced with C, and so on...\n\/\/ Finally E is replaced with F, because of left to right replacements.\n$search = array('A', 'B', 'C', 'D', 'E');\n$replace = array('B', 'C', 'D', 'E', 'F');\n$subject = 'A';\necho str_replace($search, $replace, $subject);\n\n\/\/ Outputs: apearpearle pear\n\/\/ For the same reason mentioned above\n$letters = array('a', 'p');\n$fruit = array('apple', 'pear');\n$text = 'a p';\n$output = str_replace($letters, $fruit, $text);\necho $output;", - "output": null - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/function.strrpos.html b/features/test-manual-files/function.strrpos.html deleted file mode 100644 index d22e578..0000000 --- a/features/test-manual-files/function.strrpos.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Find the position of the last occurrence of a substring in a string - - -
-
-

strrpos

-

(PHP 4, PHP 5)

strrposFind the position of the last occurrence of a substring in a string

- -
- -
-

Description

-
- int strrpos - ( string $haystack - , string $needle - [, int $offset = 0 - ] )
- -

- Find the numeric position of the last occurrence of - needle in the haystack string. -

-
- - -
-

Parameters

-

-

- - -
-haystack
- -
- -

- The string to search in. -

-
- - - -
-needle
- -
- -

- If needle is not a string, it is converted - to an integer and applied as the ordinal value of a character. -

-
- - - -
-offset
- -
- -

- If specified, search will start this number of characters counted from the - beginning of the string. If the value is negative, search will instead start - from that many characters from the end of the string, searching backwards. -

-
- - -
- -

-
- - -
-

Return Values

-

- Returns the position where the needle exists relative to the beginnning of - the haystack string (independent of search direction - or offset). - Also note that string positions start at 0, and not 1. -

-

- Returns FALSE if the needle was not found. -

-
Warning

This function may -return Boolean FALSE, but may also return a non-Boolean value which -evaluates to FALSE. Please read the section on Booleans for more -information. Use the === -operator for testing the return value of this -function.

-
- - -
-

Changelog

-

- - - - - - - - - - - - - - - - - - -
VersionDescription
5.0.0 - The needle may now be a string of more than one - character. -
- -

-
- - -
-

Examples

-

-

-

Example #1 Checking if a needle is in the haystack

-

- It is easy to mistake the return values for "character found at - position 0" and "character not found". Here's how to detect - the difference: -

-
-
-<?php

$pos 
strrpos($mystring"b");
if (
$pos === false) { // note: three equal signs
    // not found...
}

?> -
-
-
- -
-

-

-

-

Example #2 Searching with offsets

-
-
-<?php
$foo 
"0123456789a123456789b123456789c";

var_dump(strrpos($foo'7', -5));  // Starts looking backwards five positions
                                   // from the end. Result: int(17)

var_dump(strrpos($foo'7'20));  // Starts searching 20 positions into the
                                   // string. Result: int(27)

var_dump(strrpos($foo'7'28));  // Result: bool(false)
?> -
-
-
- -
-

-
- - -
-

See Also

-

-

    -
  • strpos() - Find the position of the first occurrence of a substring in a string
  • -
  • stripos() - Find the position of the first occurrence of a case-insensitive substring in a string
  • -
  • strripos() - Find the position of the last occurrence of a case-insensitive substring in a string
  • -
  • strrchr() - Find the last occurrence of a character in a string
  • -
  • substr() - Return part of a string
  • -
-

-
- - -

diff --git a/features/test-manual-files/function.strrpos.json b/features/test-manual-files/function.strrpos.json deleted file mode 100644 index 3d16bda..0000000 --- a/features/test-manual-files/function.strrpos.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "desc": "Find the position of the last occurrence of a substring in a string.", - "long_desc": "Find the numeric position of the last occurrence of `needle` in the `haystack` string.", - "ver": "PHP 4, PHP 5", - "ret_desc": "Returns the position where the needle exists relative to the beginnning of the haystack string (independent of search direction or offset). Also note that string positions start at 0, and not 1.", - "seealso": [ - "strpos", - "stripos", - "strripos", - "strrchr", - "substr" - ], - "filename": "function.strrpos", - "params": [ - { - "name": "strrpos", - "list": [ - { - "type": "string", - "var": "$haystack", - "beh": "required", - "desc": "The string to search in." - }, - { - "type": "string", - "var": "$needle", - "beh": "required", - "desc": "If `needle` is not a string, it is converted to an integer and applied as the ordinal value of a character." - }, - { - "type": "int", - "var": "$offset", - "beh": "optional", - "desc": "If specified, search will start this number of characters counted from the beginning of the string. If the value is negative, search will instead start from that many characters from the end of the string, searching backwards.", - "default": 0 - } - ], - "ret_type": "int" - } - ], - "examples": [ - { - "title": "Checking if a needle is in the haystack", - "source": "$pos = strrpos($mystring, \"b\");\nif ($pos === false) { \/\/ note: three equal signs\n \/\/ not found...\n}", - "output": null - }, - { - "title": "Searching with offsets", - "source": "$foo = \"0123456789a123456789b123456789c\";\n\nvar_dump(strrpos($foo, '7', -5)); \/\/ Starts looking backwards five positions\n \/\/ from the end. Result: int(17)\n\nvar_dump(strrpos($foo, '7', 20)); \/\/ Starts searching 20 positions into the\n \/\/ string. Result: int(27)\n\nvar_dump(strrpos($foo, '7', 28)); \/\/ Result: bool(false)", - "output": null - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/reflectionclass.getname.html b/features/test-manual-files/reflectionclass.getname.html deleted file mode 100644 index f915fbd..0000000 --- a/features/test-manual-files/reflectionclass.getname.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - Gets class name - - -
-
-

ReflectionClass::getName

-

(PHP 5)

ReflectionClass::getNameGets class name

- -
- -
-

Description

-
- public string ReflectionClass::getName - ( void - )
- -

- Gets the class name. -

- -
Warning

This function is -currently not documented; only its argument list is available. -

- -
- - -
-

Parameters

-

This function has no parameters.

-
- - -
-

Return Values

-

- The class name. -

-
- - -
-

Examples

-

-

-

Example #1 ReflectionClass::getName() example

-
-
-<?php
namespace A\B;

class 
Foo { }

$function = new \ReflectionClass('stdClass');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());

$function = new \ReflectionClass('A\\B\\Foo');

var_dump($function->inNamespace());
var_dump($function->getName());
var_dump($function->getNamespaceName());
var_dump($function->getShortName());
?> -
-
-
- -

The above example will output:

-
-
-bool(false)
-string(8) "stdClass"
-string(0) ""
-string(8) "stdClass"
-
-bool(true)
-string(7) "A\B\Foo"
-string(3) "A\B"
-string(3) "Foo"
-
-
-
-

-
- - -
-

See Also

-

-

-

-
- - -

diff --git a/features/test-manual-files/reflectionclass.getname.json b/features/test-manual-files/reflectionclass.getname.json deleted file mode 100644 index 9f7a842..0000000 --- a/features/test-manual-files/reflectionclass.getname.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "desc": "Gets class name.", - "long_desc": "Gets the class name.\\n\\nThis function is currently not documented; only its argument list is available.", - "ver": "PHP 5", - "ret_desc": "The class name.", - "seealso": [ - "ReflectionClass::getNamespaceName" - ], - "filename": "reflectionclass.getname", - "params": [ - { - "name": "ReflectionClass::getName", - "list": [], - "ret_type": "string" - } - ], - "examples": [ - { - "title": "ReflectionClass::getName() example", - "source": "namespace A\\B;\n\nclass Foo { }\n\n$function = new \\ReflectionClass('stdClass');\n\nvar_dump($function->inNamespace());\nvar_dump($function->getName());\nvar_dump($function->getNamespaceName());\nvar_dump($function->getShortName());\n\n$function = new \\ReflectionClass('A\\\\B\\\\Foo');\n\nvar_dump($function->inNamespace());\nvar_dump($function->getName());\nvar_dump($function->getNamespaceName());\nvar_dump($function->getShortName());", - "output": "bool(false)\nstring(8) \"stdClass\"\nstring(0) \"\"\nstring(8) \"stdClass\"\n\nbool(true)\nstring(7) \"A\\B\\Foo\"\nstring(3) \"A\\B\"\nstring(3) \"Foo\"" - } - ] -} \ No newline at end of file diff --git a/features/test-manual-files/splfileobject.fgetcsv.html b/features/test-manual-files/splfileobject.fgetcsv.html deleted file mode 100644 index d1571e0..0000000 --- a/features/test-manual-files/splfileobject.fgetcsv.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - Gets line from file and parse as CSV fields - - -
-
-

SplFileObject::fgetcsv

-

(PHP 5 >= 5.1.0)

SplFileObject::fgetcsvGets line from file and parse as CSV fields

- -
- -
-

Description

-
- public array SplFileObject::fgetcsv - ([ string $delimiter = "," - [, string $enclosure = "\"" - [, string $escape = "\\" - ]]] )
- -

- Gets a line from the file which is in CSV format and returns an array containing the fields read. -

-
- - -
-

Parameters

-

-

- - -
-delimiter
- -
- -

- The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl(). -

-
- - - -
-enclosure
- -
- -

- The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl(). -

-
- - - -
-escape
- -
- -

- The escape character (one character only). Defaults as a backslash (\) or the value set using SplFileObject::setCsvControl(). -

-
- - -
- -

-
- - -
-

Return Values

-

- Returns an indexed array containing the fields read, or FALSE on error. -

-

Note: -

- A blank line in a CSV file will be returned as an array - comprising a single NULL field unless using SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE, - in which case empty lines are skipped. -

-

-
- - -
-

Examples

-

-

-

Example #1 SplFileObject::fgetcsv() example

-
-
-<?php
$file 
= new SplFileObject("data.csv");
while (!
$file->eof()) {
    
var_dump($file->fgetcsv());
}
?> -
-
-
- -
-

-

-

-

Example #2 SplFileObject::READ_CSV example

-
-
-<?php
$file 
= new SplFileObject("animals.csv");
$file->setFlags(SplFileObject::READ_CSV);
foreach (
$file as $row) {
    list(
$animal$class$legs) = $row;
    
printf("A %s is a %s with %d legs\n"$animal$class$legs);
}
?> -
-
-
- -

Contents of animals.csv

-
-
crocodile,reptile,4
-dolphin,mammal,0
-duck,bird,2
-koala,mammal,4
-salmon,fish,0
-
-
- -

The above example will output -something similar to:

-
-
-A crocodile is a reptile with 4 legs
-A dolphin is a mammal with 0 legs
-A duck is a bird with 2 legs
-A koala is a mammal with 4 legs
-A salmon is a fish with 0 legs
-
-
-
-

-
- - -
-

See Also

-

-

-

-
- - -

diff --git a/features/test-manual-files/splfileobject.fgetcsv.json b/features/test-manual-files/splfileobject.fgetcsv.json deleted file mode 100644 index 44279ee..0000000 --- a/features/test-manual-files/splfileobject.fgetcsv.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "desc": "Gets line from file and parse as CSV fields.", - "long_desc": "Gets a line from the file which is in CSV format and returns an array containing the fields read.", - "ver": "PHP 5 >= 5.1.0", - "ret_desc": "Returns an indexed array containing the fields read, or FALSE on error.", - "seealso": [ - "SplFileObject::setCsvControl", "SplFileObject::setFlags", "SplFileObject::READ_CSV", "SplFileObject::current" - ], - "filename": "splfileobject.fgetcsv", - "params": [ - { - "name": "SplFileObject::fgetcsv", - "list": [ - { - "type": "string", - "var": "$delimiter", - "beh": "optional", - "desc": "The field delimiter (one character only). Defaults as a comma or the value set using SplFileObject::setCsvControl().", - "default": "\",\"" - }, - { - "type": "string", - "var": "$enclosure", - "beh": "optional", - "desc": "The field enclosure character (one character only). Defaults as a double quotation mark or the value set using SplFileObject::setCsvControl().", - "default": "\"\\\"\"" - }, - { - "type": "string", - "var": "$escape", - "beh": "optional", - "desc": "The escape character (one character only). Defaults as a backslash (`\\`) or the value set using SplFileObject::setCsvControl().", - "default": "\"\\\\\"" - } - ], - "ret_type": "array" - } - ], - "examples": [ - { - "title": "SplFileObject::fgetcsv() example", - "source": "$file = new SplFileObject(\"data.csv\");\nwhile (!$file->eof()) {\n var_dump($file->fgetcsv());\n}", - "output": null - }, - { - "title": "SplFileObject::READ_CSV example", - "source": "$file = new SplFileObject(\"animals.csv\");\n$file->setFlags(SplFileObject::READ_CSV);\nforeach ($file as $row) {\n list($animal, $class, $legs) = $row;\n printf(\"A %s is a %s with %d legs\\n\", $animal, $class, $legs);\n}", - "output": "A crocodile is a reptile with 4 legs\nA dolphin is a mammal with 0 legs\nA duck is a bird with 2 legs\nA koala is a mammal with 4 legs\nA salmon is a fish with 0 legs" - } - ] -} \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..5912aeb --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,7 @@ + + + + tests + + + \ No newline at end of file diff --git a/src/Parser.php b/src/Parser.php index 495b81d..0d79b06 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -2,9 +2,6 @@ namespace DocParser; -use Symfony\Component\Filesystem\Filesystem; -use DocParser\Utils; - class Parser { /** * Process all files in the directory with selected by getFilesToProcess() method. @@ -14,12 +11,12 @@ class Parser { * @param callable $progressCallback Optional callback used to monitor progress * @return ParserResult Parse result including all warnings and skipped files */ - public function processDir($dir, $parseExamples = true, \Closure $progressCallback = null) { + public function processDir($dir, $parseExamples = true, callable $progressCallback = null) { $results = new ParserResult(); $files = $this->getFilesToProcess($dir); $processed = 0; - // Parse each file. + // Parse each file foreach ($files as $file) { $progressCallback(basename($file), count($files), $processed); $this->processFile($file, $parseExamples, $results); @@ -41,6 +38,7 @@ public function getFilesToProcess($dir) { * * @param string $file Source file * @param boolean $parseExamples Whether or not include also examples + * @throws \Exception * @return ParserResult Parse result including all warnings and skipped files */ public function processFile($file, $parseExamples = true, $result = null) { @@ -59,7 +57,7 @@ public function processFile($file, $parseExamples = true, $result = null) { $function = []; - // Parse function name. + // Parse function name $h1 = $xpath->query('//h1[@class="refname"]'); // Check if it managed to find function name. @@ -68,7 +66,7 @@ public function processFile($file, $parseExamples = true, $result = null) { return $result; } - // Function short description. + // Function short description $description = $xpath->query('//span[@class="dc-title"]'); if ($description->length > 0) { // some functions don't have any description $function['desc'] = trim(Utils::simplifyString($description->item(0)->textContent), '.') . '.'; @@ -83,7 +81,7 @@ public function processFile($file, $parseExamples = true, $result = null) { $function['long_desc'] = trim($function['long_desc'], '.') . '.'; } - // PHP version since this function is available. + // PHP version since this function is available $version = $xpath->query('//p[@class="verinfo"]'); if ($version->length > 0) { // check from which PHP version is it available $function['ver'] = trim($version->item(0)->textContent, '()'); @@ -121,7 +119,7 @@ public function processFile($file, $parseExamples = true, $result = null) { $function['params'] = []; $funcDescription = $xpath->query('//div[@class="refsect1 description"]/div[@class="methodsynopsis dc-description"]'); foreach ($funcDescription as $index => $description) { - // Function name for this parameter list. + // Function name for this parameter list $altName = str_replace('->', '::', $xpath->query('./span[@class="methodname"]', $description)->item(0)->textContent); $parsedParams = [ 'list' => [], @@ -134,7 +132,7 @@ public function processFile($file, $parseExamples = true, $result = null) { $parsedParams['ret_type'] = $span->item(0)->textContent; } - // Parameter containers. + // Parameter containers $params = $xpath->query('span[@class="methodparam"]', $description); // skip empty parameter list (function declaration that doesn't take any parameter) @@ -156,13 +154,12 @@ public function processFile($file, $parseExamples = true, $result = null) { } } - // Single parameter. + // Single parameter $param = array( 'type' => $paramNodes->item(0) ? $paramNodes->item(0)->textContent : 'unknown', // type 'var' => $varName, // variable name 'beh' => $params->length - $optional > $i ? 'required' : 'optional', // required/optional - // parameter description - 'desc' => $paramDescriptions ? Utils::extractFormattedText($xpath->query($descPattern, $paramDescriptions->item(0)), $xpath) : null, + 'desc' => $paramDescriptions ? Utils::extractFormattedText($xpath->query($descPattern, $paramDescriptions->item(0)), $xpath) : null, // parameter description ); // Default value for this parameter if ($paramNodes->length >= 3) { @@ -188,14 +185,14 @@ public function processFile($file, $parseExamples = true, $result = null) { } $funcName = $names[0]; - // Use all alternative names just as a reference to the first (primary) name. + // Use all alternative names just as a reference to the first (primary) name foreach (array_unique($names) as $index => $name) { $result->setResult($name, $index == 0 ? $function : $funcName); } - // Parse all examples in this file. + // Parse all examples in this file if ($parseExamples) { - // Find all source code containers. + // Find all source code containers $exampleDiv = $xpath->query('//div[@class="example" or @class="informalexample"]'); for ($i=0; $i < $exampleDiv->length; $i++) { $output = null; @@ -206,11 +203,11 @@ public function processFile($file, $parseExamples = true, $result = null) { $output = $xpath->query('.//div[@class="cdata"]', $exampleDiv->item($i))->item(0)->textContent; } - // Example title, strip beginning and ending php tags. + // Example title, strip beginning and ending php tags $ps = $xpath->query('p', $exampleDiv->item($i)); if ($ps->length > 0) { $title = $ps->item(0)->textContent; - // Remove some unnecessary stuff. + // Remove some unnecessary stuff $title = trim(preg_replace('/^(Example #\d+|Beispiel #\d+|Exemplo #\d+|Exemple #\d+|Przykład #\d+)/', '', $title)); $title = trim(preg_replace('/\s+/', ' ', $title)); } else { @@ -223,7 +220,7 @@ public function processFile($file, $parseExamples = true, $result = null) { 'output' => trim($output) ?: null, ]; - // Skip examples with malformed UTF-8 characters. + // Skip examples with malformed UTF-8 characters // @todo: check where's the problem json_encode($example, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE); if (json_last_error()) { diff --git a/tests/ParserResultTest.php b/tests/ParserResultTest.php new file mode 100644 index 0000000..3362cd3 --- /dev/null +++ b/tests/ParserResultTest.php @@ -0,0 +1,83 @@ +setResult($file, $row[3]); + if ($row[4]) { + foreach (explode(',', $row[4]) as $example) { + $result->addExample($file, trim($example)); + } + } + + if ($row[1]) { + foreach (explode(',', $row[1]) as $warning) { + $result->addWarning($file, trim($warning)); + } + } + + if ($row[2]) { + $result->addSkipped($file); + } + + if (isset($allResults[$file])) { + $allResults[$file]->mergeWithResult($result); + } else { + $allResults[$file] = $result; + } + } + + // Check results + $mergedResult = new ParserResult(); + foreach ($allResults as $r) { + $mergedResult->mergeWithResult($r); + } + + $warningsCount = $examplesCount = 0; + foreach ($expected as $row) { + $file = $row[0]; + + $warningsCount += count(explode(',', $row[1])); + $examplesCount += count(explode(',', $row[4])); + + $this->assertEquals(array_map(function($s) { return trim ($s); }, explode(',', $row[1])), $mergedResult->getWarnings($file)); + $this->assertEquals(array_map(function($s) { return trim ($s); }, explode(',', $row[4])), $mergedResult->getExamples($file)); + $this->assertEquals($row[3], $mergedResult->getResult($file)); + if ($row[2]) { + assertTrue($mergedResult->isSkipped($file)); + } else { + assertFalse($mergedResult->isSkipped($file)); + } + } + + $this->assertEquals($warningsCount, $mergedResult->countAllWarnings()); + $this->assertEquals($examplesCount, $mergedResult->countAllExamples()); + } + +} \ No newline at end of file From 73a3d1c013c8c9ace45c035378d5a5dbda5fe23e Mon Sep 17 00:00:00 2001 From: Martin Sikora Date: Mon, 21 Aug 2017 11:46:29 +0200 Subject: [PATCH 4/4] remove PHP 5.6 support --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7085abd..952f91d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: php php: - - '5.6' - '7.0' - '7.1' script: