diff --git a/.gitattributes b/.gitattributes index 8e184d6..a66312a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,6 @@ /bin export-ignore /dev-tools export-ignore +/examples export-ignore /tests export-ignore /.coveralls.yml export-ignore /.gitattributes export-ignore diff --git a/.php_cs.dist b/.php_cs.dist index de8e005..be9eaca 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -2,6 +2,7 @@ $finder = PhpCsFixer\Finder::create() ->in(__DIR__ . DIRECTORY_SEPARATOR . 'bin') + ->in(__DIR__ . DIRECTORY_SEPARATOR . 'examples') ->in(__DIR__ . DIRECTORY_SEPARATOR . 'src') ->in(__DIR__ . DIRECTORY_SEPARATOR . 'tests') ->notName('StackTraceTest.php') @@ -23,7 +24,6 @@ return PhpCsFixer\Config::create() 'no_unused_imports' => true, 'yoda_style' => true, 'new_with_braces' => true, - 'mb_str_functions' => true, 'native_function_invocation' => true, 'header_comment' => array('header' => $header), 'phpdoc_align' => true, diff --git a/.travis.yml b/.travis.yml index e7af6d9..23acdb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,6 @@ php: - hhvm-3.15 - hhvm-3.18 - hhvm-nightly - -allow_failures: - - php: nightly - - php: hhvm-nightly env: matrix: @@ -30,6 +26,10 @@ env: - DEPENDENCIES="low" matrix: + allow_failures: + - php: nightly + - php: hhvm-nightly + include: - php: 5.3 dist: precise @@ -74,6 +74,7 @@ before_script: script: - if [[ "$RUN_CS_FIXER" = "true" ]]; then php -n ${PHP_CS_FIXER} --diff --dry-run -v --allow-risky=yes fix; fi - php ${PHP_ARGS} vendor/bin/phpunit + - php ${PHP_ARGS} examples/read-arguments.php after_script: - mv ~.git .git diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f43286..f9981ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.12.0 (????-??-??) + +* Removed deprecated method `Awesomite\StackTrace\Arguments\Values\ValueInterface::getDump` + ## 0.11.0 (2018-01-14) * Updated `awesomite/var-dumper` diff --git a/LICENSE b/LICENSE index f6d82ae..b6bf2b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,19 @@ Copyright (c) 2016 - 2018 Bartłomiej Krukowski -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 1ec37f0..26cf06a 100644 --- a/README.md +++ b/README.md @@ -5,23 +5,42 @@ [![Build Status](https://travis-ci.org/awesomite/stack-trace.svg?branch=master)](https://travis-ci.org/awesomite/stack-trace) Abstract layer for [`debug_backtrace()`](http://php.net/manual/en/function.debug-backtrace.php) function. +This library allows you to serialize whole stack trace including variables. +It handles all types of data, including resources. ## Usage See [documentation](docs/DOCUMENTATION.md). ```php +create(); foreach ($stackTrace as $step) { - $placeInCode = $step->getPlaceInCode(); - $line = $placeInCode->getLineNumber(); - $fileName = $placeInCode->getFileName(); + /** @var StepInterface $step */ + $function = $step->getCalledFunction()->getName(); - echo "Function {$function} is called from {$fileName}:{$line}\n"; + echo "Function {$function}"; + + if ($step->hasPlaceInCode()) { + /** @var PlaceInCodeInterface $placeInCode */ + $placeInCode = $step->getPlaceInCode(); + $fileName = $placeInCode->getFileName(); + $line = $placeInCode->getLineNumber(); + $function = $step->getCalledFunction()->getName(); + echo " is called from {$fileName}:{$line}"; + } + + echo "\n"; } + +$data = serialize($stackTrace); +$unserializedStackTrace = unserialize($data); ``` ## Installation @@ -33,6 +52,10 @@ foreach ($stackTrace as $step) { The version numbers follow the [Semantic Versioning 2.0.0](http://semver.org/) scheme. [Read more](docs/DOCUMENTATION.md#backward-compatibility) about backward compatibility. -## Running tests +## Examples + +[See](examples) more examples. + +## License -See [documentation](docs/TESTS.md) for tests. +This library is released under the [MIT license](LICENSE). diff --git a/bin/fix-phpunit.php b/bin/fix-phpunit.php deleted file mode 100755 index 1673020..0000000 --- a/bin/fix-phpunit.php +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env php -getFileName(); -$contents = \file_get_contents($file); - -$contents = \str_replace('= each(', '= awesomite_each(', $contents); -\file_put_contents($file, $contents); diff --git a/bin/hhvm-tests.sh b/bin/hhvm-tests.sh deleted file mode 100755 index 3f21092..0000000 --- a/bin/hhvm-tests.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e - -BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -PROJECT_DIR=$(dirname ${BIN_DIR}) - -docker run -it --rm --name my-running-script -v "$PROJECT_DIR":/usr/src/myapp -w /usr/src/myapp diegomarangoni/hhvm:cli hhvm vendor/bin/phpunit ${@} diff --git a/bin/hhvm.sh b/bin/hhvm.sh deleted file mode 100755 index 41ed8d3..0000000 --- a/bin/hhvm.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp diegomarangoni/hhvm:cli hhvm ${@} diff --git a/bin/install-composer.php b/bin/install-composer.php deleted file mode 100755 index 15c029a..0000000 --- a/bin/install-composer.php +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env php -=1.2.3", "symfony/console": "^2.7 || ^3.0", "awesomite/phpunit-4.8-fixer": "^1.0" - } + }, + "keywords": ["debug", "debug_backtrace"] } diff --git a/docs/TESTS.md b/docs/TESTS.md deleted file mode 100644 index d8a55b5..0000000 --- a/docs/TESTS.md +++ /dev/null @@ -1,68 +0,0 @@ -# Tests - -StackTrace is fully tested on versions of PHP between 5.3 and 7.1. -This guide describes how to execute tests. - -## Table of contents - -1. [Production environment](#production-environment) -2. [Local environment with docker](#local-environment-with-docker) -3. [HHVM](#hhvm) - -## Production environment - -If you want to execute tests on your production environment, -execute the following commands on root directory of this project: - -```bash -composer update --dev -vendor/bin/phpunit -``` - -### Requirements - -* [composer](https://getcomposer.org/) -* `php ^5.3 || ^7.0` - -## Local environment with docker - -The following command executes test on your local computer. -Dependencies will be installed automatically in `build` directory. -Tests will be executed on all available versions of PHP. -You will need docker image [`splitbrain/phpfarm:jessie`](https://github.com/splitbrain/docker-phpfarm). -Image will be installed automatically if does not exist on your local computer. - -```bash -bin/local-tests-docker.sh -``` - -If you want to execute test on specified version of PHP, -add optional argument `VERSION`. - -```bash -VERSION=7.0 -bin/local-tests-docker.sh ${VERSION} -``` - -Argument `VERSION` can be equal to one of below values: - -* `5.3` -* `5.4` -* `5.5` -* `5.6` -* `7.0` -* `7.1` - -### Requirements - -* [docker](https://www.docker.com/) -* `php ^5.3 || ^7.0` - -## HHVM - -* Tests - `bin/hhvm-tests.sh` -* Interpreter - `bin/hhvm.sh` - -### Requirements - -* [docker](https://www.docker.com/) diff --git a/examples/StackTracePrinter.php b/examples/StackTracePrinter.php new file mode 100644 index 0000000..433d381 --- /dev/null +++ b/examples/StackTracePrinter.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Awesomite\StackTrace\Arguments\ArgumentInterface; +use Awesomite\StackTrace\Arguments\ArgumentsInterface; +use Awesomite\StackTrace\StackTraceFactory; +use Awesomite\StackTrace\Steps\StepInterface; + +/** + * @internal + */ +class StackTracePrinter +{ + public function printStackTrace() + { + $factory = new StackTraceFactory(); + $stackTrace = $factory->create(); + $i = 0; + foreach ($stackTrace as $step) { + $this->printStep($step, ++$i); + } + } + + private function printStep(StepInterface $step, $i) + { + $function = $step->getCalledFunction()->getName(); + + echo "#{$i} {$function}("; + $arguments = $step->getArguments(); + $first = true; + foreach ($arguments as $argument) { + if ($argument->hasDeclaration()) { + if ($first) { + $first = false; + } else { + echo ', '; + } + + echo '$' . $argument->getDeclaration()->getName(); + } else { + break; + } + } + echo ")\n"; + + if ($step->hasPlaceInCode()) { + echo " Place in code:\n"; + $placeInCode = $step->getPlaceInCode(); + $fileName = $this->shortFileName($placeInCode->getFileName()); + echo " {$fileName}:{$placeInCode->getLineNumber()}\n"; + } + + $this->printArguments($step->getArguments()); + } + + /** + * @param ArgumentsInterface|ArgumentInterface[] $arguments + */ + private function printArguments($arguments) + { + if (!\count($arguments)) { + return; + } + + echo " Arguments:\n"; + + foreach ($arguments as $argument) { + $dump = $argument->hasValue() + ? $argument->getValue()->dumpAsString() + : "undefined\n"; + + $tabs = " "; + + $dump = \substr($dump, 0, -1); + $dump = $tabs . \str_replace("\n", "\n", $dump) . "\n"; + echo $dump; + } + } + + private function shortFileName($file) + { + $exploded = \explode(DIRECTORY_SEPARATOR, $file); + $shifted = false; + while (\count($exploded) > 3) { + \array_shift($exploded); + $shifted = true; + } + + if ($shifted) { + \array_unshift($exploded, '(...)'); + } + + + return \implode(DIRECTORY_SEPARATOR, $exploded); + } +} diff --git a/examples/read-arguments.php b/examples/read-arguments.php new file mode 100644 index 0000000..76c4abd --- /dev/null +++ b/examples/read-arguments.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +require \implode(DIRECTORY_SEPARATOR, array(__DIR__, '..', 'vendor', 'autoload.php')); +require __DIR__ . DIRECTORY_SEPARATOR . 'StackTracePrinter.php'; + +/** + * @internal + * + * @param $arg1 + * @param $arg2 + */ +function myFirstFunction($arg1, $arg2) +{ + mySecondFunction('foo', 'bar'); +} + +/** + * @internal + * + * @param $foo + * @param $bar + */ +function mySecondFunction($foo, $bar) +{ + myThirdFunction(\tmpfile(), M_PI); +} + +/** + * @internal + * + * @param $argument1 + * @param $argument2 + */ +function myThirdFunction($argument1, $argument2) +{ + $printer = new StackTracePrinter(); + $printer->printStackTrace(); +} + +myFirstFunction('hello', 'world'); + +/* + +Output: + +#1 Awesomite\StackTrace\StackTraceFactory->create($stepLimit, $ignoreArgs) + Place in code: + (...)/stack-trace/examples/StackTracePrinter.php:25 + Arguments: + undefined + undefined +#2 StackTracePrinter->printStackTrace() + Place in code: + (...)/stack-trace/examples/read-arguments.php:46 +#3 myThirdFunction($argument1, $argument2) + Place in code: + (...)/stack-trace/examples/read-arguments.php:34 + Arguments: + resource #10 of type stream + M_PI +#4 mySecondFunction($foo, $bar) + Place in code: + (...)/stack-trace/examples/read-arguments.php:23 + Arguments: + “foo” + “bar” +#5 myFirstFunction($arg1, $arg2) + Place in code: + (...)/stack-trace/examples/read-arguments.php:49 + Arguments: + “hello” + “world” + +*/ diff --git a/src/Arguments/Values/DeserializedValue.php b/src/Arguments/Values/DeserializedValue.php index a4e9651..08a55aa 100644 --- a/src/Arguments/Values/DeserializedValue.php +++ b/src/Arguments/Values/DeserializedValue.php @@ -41,11 +41,6 @@ public function dumpAsString() return $this->dumpedVariable; } - public function getDump() - { - return $this->dumpAsString(); - } - public function getRealValue() { throw new CannotRestoreValueException('Cannot restore value!'); diff --git a/src/Arguments/Values/Value.php b/src/Arguments/Values/Value.php index 67709d8..b622b5b 100644 --- a/src/Arguments/Values/Value.php +++ b/src/Arguments/Values/Value.php @@ -71,11 +71,6 @@ public function dumpAsString() return $result; } - public function getDump() - { - return $this->dumpAsString(); - } - public function isRealValueReadable() { return true; diff --git a/src/Arguments/Values/ValueInterface.php b/src/Arguments/Values/ValueInterface.php index ce945b4..6b9c3d0 100644 --- a/src/Arguments/Values/ValueInterface.php +++ b/src/Arguments/Values/ValueInterface.php @@ -32,12 +32,5 @@ public function dump(); */ public function dumpAsString(); - /** - * @deprecated - * - * @return mixed - */ - public function getDump(); - public function __toString(); } diff --git a/src/Functions/AFunction.php b/src/Functions/AFunction.php index f567c34..a3bec3e 100644 --- a/src/Functions/AFunction.php +++ b/src/Functions/AFunction.php @@ -48,7 +48,7 @@ public function getName() public function isClosure() { - return false !== \mb_strpos($this->arrayStep['function'], '{closure}'); + return false !== \strpos($this->arrayStep['function'], '{closure}'); } public function isInClass() @@ -108,7 +108,7 @@ private function hasDeprecatedTag(\ReflectionFunctionAbstract $function) { $comment = $function->getDocComment(); - return false !== $comment && false !== \mb_strpos($comment, '@deprecated'); + return false !== $comment && false !== \strpos($comment, '@deprecated'); } private function createReflection() diff --git a/src/StackTrace.php b/src/StackTrace.php index 4fa620c..8424d23 100644 --- a/src/StackTrace.php +++ b/src/StackTrace.php @@ -27,8 +27,8 @@ */ class StackTrace implements StackTraceInterface { - const VERSION = '0.11.0'; - const CONSTRAINTS_VERSION = '^0.11.0'; + const VERSION = '0.12.0'; + const CONSTRAINTS_VERSION = '^0.12.0'; private $arrayStackTrace; diff --git a/tests/Arguments/Values/DeserializedValueTest.php b/tests/Arguments/Values/DeserializedValueTest.php index 847b8c5..47ed7c9 100644 --- a/tests/Arguments/Values/DeserializedValueTest.php +++ b/tests/Arguments/Values/DeserializedValueTest.php @@ -25,7 +25,6 @@ public function testAll($dump) $value = new DeserializedValue($dump); $this->assertSame($dump, (string)$value); $this->assertSame($dump, $value->dumpAsString()); - $this->assertSame($dump, $value->getDump()); $this->assertFalse($value->isRealValueReadable()); $this->expectOutputString($dump); $value->dump(); diff --git a/tests/Arguments/Values/ValueTest.php b/tests/Arguments/Values/ValueTest.php index b9a15e8..3f5518e 100644 --- a/tests/Arguments/Values/ValueTest.php +++ b/tests/Arguments/Values/ValueTest.php @@ -29,7 +29,6 @@ public function testAll(Value $value, $expectedRealValue) $this->assertTrue($value->isRealValueReadable()); $this->assertSame($expectedRealValue, $value->getRealValue()); $this->assertSame($value->dumpAsString(), (string)$value); - $this->assertSame($value->getDump(), (string)$value); $this->expectOutputString($value->dumpAsString()); $value->dump(); } @@ -65,10 +64,6 @@ public function testSerialize(Value $value) /** @var Value $restored */ $restored = \unserialize(\serialize($value)); $this->assertSame($value->dumpAsString(), $restored->dumpAsString()); - - $this->assertSame($value->dumpAsString(), $restored->getDump()); - $this->assertSame($value->getDump(), $restored->dumpAsString()); - $this->assertSame((string)$value, $restored->dumpAsString()); $this->assertSame($value->getRealValue(), $restored->getRealValue()); }