mirror of
https://github.com/halaxa/json-machine.git
synced 2025-01-17 21:18:23 +01:00
Merge branch 'master' into pr-61-multiple-json-pointers
This commit is contained in:
commit
ac1ae06f96
@ -7,9 +7,11 @@ $finder = PhpCsFixer\Finder::create()
|
||||
|
||||
$config = new PhpCsFixer\Config();
|
||||
return $config->setRules([
|
||||
'@PSR12' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'@Symfony' => true,
|
||||
'yoda_style' => false,
|
||||
'single_line_throw' => false,
|
||||
'unary_operator_spaces' => false,
|
||||
'visibility_required' => false,
|
||||
])
|
||||
->setFinder($finder)
|
||||
;
|
||||
;
|
||||
|
@ -7,7 +7,7 @@
|
||||
- Removed deprecated `Decoder` interface.
|
||||
|
||||
### Changed
|
||||
- Default decoding structure of `Parser` is object. (You don't notice unless you use `Parser` class directly)
|
||||
- Default decoding structure of `Parser` is object. (You won't notice that unless you use `Parser` class directly)
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
@ -11,7 +11,6 @@ class DebugLexer implements \IteratorAggregate, PositionAware
|
||||
private $line = 1;
|
||||
private $column = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param iterable<string> $jsonChunks
|
||||
*/
|
||||
@ -120,7 +119,9 @@ class DebugLexer implements \IteratorAggregate, PositionAware
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer The line number of the lexeme currently being processed (index starts at one).
|
||||
* Returns the line number of the lexeme currently being processed (index starts at one).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
@ -128,7 +129,9 @@ class DebugLexer implements \IteratorAggregate, PositionAware
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer The, currently being processed, lexeme's position within the line (index starts at one).
|
||||
* The position of currently being processed lexeme within the line (index starts at one).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getColumn()
|
||||
{
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace JsonMachine;
|
||||
|
||||
use JsonMachine\Exception\InvalidArgumentException;
|
||||
|
||||
class FileChunks implements \IteratorAggregate
|
||||
{
|
||||
/** @var string */
|
||||
@ -14,7 +12,7 @@ class FileChunks implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param int $chunkSize
|
||||
* @param int $chunkSize
|
||||
*/
|
||||
public function __construct($fileName, $chunkSize = 1024 * 8)
|
||||
{
|
||||
|
@ -3,11 +3,11 @@
|
||||
namespace JsonMachine;
|
||||
|
||||
use JsonMachine\Exception\InvalidArgumentException;
|
||||
use JsonMachine\JsonDecoder\ItemDecoder;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
use JsonMachine\JsonDecoder\ItemDecoder;
|
||||
|
||||
/**
|
||||
* Entry-point facade for JSON Machine
|
||||
* Entry-point facade for JSON Machine.
|
||||
*/
|
||||
final class Items implements \IteratorAggregate, PositionAware
|
||||
{
|
||||
@ -37,10 +37,11 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
private $debugEnabled;
|
||||
|
||||
/**
|
||||
* @param iterable $bytesIterator
|
||||
* @param array|string $jsonPointer
|
||||
* @param iterable $bytesIterator
|
||||
* @param array|string $jsonPointer
|
||||
* @param ItemDecoder $jsonDecoder
|
||||
* @param bool $debugEnabled
|
||||
* @param bool $debugEnabled
|
||||
*
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public function __construct($bytesIterator, $jsonPointer = '', ItemDecoder $jsonDecoder = null, $debugEnabled = false)
|
||||
@ -67,8 +68,9 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param array $options
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function fromString($string, array $options = [])
|
||||
@ -80,8 +82,9 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param array $options
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function fromFile($file, array $options = [])
|
||||
@ -93,8 +96,9 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
|
||||
/**
|
||||
* @param resource $stream
|
||||
* @param array $options
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function fromStream($stream, array $options = [])
|
||||
@ -106,8 +110,9 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
|
||||
/**
|
||||
* @param iterable $iterable
|
||||
* @param array $options
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @throws Exception\InvalidArgumentException
|
||||
*/
|
||||
public static function fromIterable($iterable, array $options = [])
|
||||
@ -133,8 +138,8 @@ final class Items implements \IteratorAggregate, PositionAware
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return array{pointer: string, decoder: ItemDecoder, debug: bool}
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private static function normalizeOptions(array $options)
|
||||
|
@ -8,7 +8,6 @@ class DecodingError
|
||||
private $errorMessage;
|
||||
|
||||
/**
|
||||
* DecodingError constructor.
|
||||
* @param string $malformedJson
|
||||
* @param string $errorMessage
|
||||
*/
|
||||
|
@ -20,6 +20,7 @@ class ErrorWrappingDecoder implements ItemDecoder
|
||||
if (! $result->isOk()) {
|
||||
return new ValidResult(new DecodingError($jsonScalarKey, $result->getErrorMessage()));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -29,6 +30,7 @@ class ErrorWrappingDecoder implements ItemDecoder
|
||||
if (! $result->isOk()) {
|
||||
return new ValidResult(new DecodingError($jsonValue, $result->getErrorMessage()));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ class ExtJsonDecoder implements ItemDecoder
|
||||
if ($decoded === null && $jsonValue !== 'null') {
|
||||
return new InvalidResult(json_last_error_msg());
|
||||
}
|
||||
|
||||
return new ValidResult($decoded);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ trait ExtJsonDecoding
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
|
||||
public function decodeKey($jsonScalarKey)
|
||||
{
|
||||
// inlined
|
||||
@ -34,6 +33,7 @@ trait ExtJsonDecoding
|
||||
if ($decoded === null && $jsonScalarKey !== 'null') {
|
||||
return new InvalidResult(json_last_error_msg());
|
||||
}
|
||||
|
||||
return new ValidResult($decoded);
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ trait ExtJsonDecoding
|
||||
if ($decoded === null && $jsonScalarKey !== 'null') {
|
||||
return new InvalidResult(json_last_error_msg());
|
||||
}
|
||||
|
||||
return new ValidStringResult($decoded);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class Lexer implements \IteratorAggregate, PositionAware
|
||||
foreach (range(0, 255) as $ord) {
|
||||
if (! in_array(
|
||||
chr($ord),
|
||||
["\\", '"', "\xEF", "\xBB", "\xBF", ' ', "\n", "\r", "\t", '{', '}', '[', ']', ':', ',']
|
||||
['\\', '"', "\xEF", "\xBB", "\xBF", ' ', "\n", "\r", "\t", '{', '}', '[', ']', ':', ',']
|
||||
)) {
|
||||
${chr($ord)} = true;
|
||||
}
|
||||
@ -96,7 +96,7 @@ class Lexer implements \IteratorAggregate, PositionAware
|
||||
$utf8bom1 => true,
|
||||
$utf8bom2 => true,
|
||||
$utf8bom3 => true,
|
||||
' ' => true,
|
||||
' ' => true,
|
||||
"\n" => true,
|
||||
"\r" => true,
|
||||
"\t" => true,
|
||||
|
@ -7,8 +7,8 @@ use JsonMachine\Exception\JsonMachineException;
|
||||
use JsonMachine\Exception\PathNotFoundException;
|
||||
use JsonMachine\Exception\SyntaxError;
|
||||
use JsonMachine\Exception\UnexpectedEndSyntaxErrorException;
|
||||
use JsonMachine\JsonDecoder\ItemDecoder;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
use JsonMachine\JsonDecoder\ItemDecoder;
|
||||
use Traversable;
|
||||
|
||||
class Parser implements \IteratorAggregate, PositionAware
|
||||
@ -45,8 +45,7 @@ class Parser implements \IteratorAggregate, PositionAware
|
||||
private $jsonDecoder;
|
||||
|
||||
/**
|
||||
* @param Traversable $lexer
|
||||
* @param array|string $jsonPointer Follows json pointer RFC https://tools.ietf.org/html/rfc6901
|
||||
* @param array|string $jsonPointer Follows json pointer RFC https://tools.ietf.org/html/rfc6901
|
||||
* @param ItemDecoder $jsonDecoder
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
@ -210,14 +209,14 @@ class Parser implements \IteratorAggregate, PositionAware
|
||||
}
|
||||
$tokenType = ${$token[0]};
|
||||
if (0 === ($tokenType & $expectedType)) {
|
||||
$this->error("Unexpected symbol", $token);
|
||||
$this->error('Unexpected symbol', $token);
|
||||
}
|
||||
$isValue = ($tokenType | 23) === 23; // 23 = self::ANY_VALUE
|
||||
if (!$inObject && $isValue && $currentLevel < $iteratorLevel) {
|
||||
$currentPathChanged = true;
|
||||
$currentPath[$currentLevel] = isset($currentPath[$currentLevel]) ? (string)(1+(int)$currentPath[$currentLevel]) : "0";
|
||||
$currentPath[$currentLevel] = isset($currentPath[$currentLevel]) ? (string) (1 + (int) $currentPath[$currentLevel]) : '0';
|
||||
$currentPathWildcard[$currentLevel] = preg_match('/^(?:\d+|-)$/', $jsonPointerPath[$currentLevel]) ? '-' : $currentPath[$currentLevel];
|
||||
unset($currentPath[$currentLevel+1], $currentPathWildcard[$currentLevel+1], $stack[$currentLevel+1]);
|
||||
unset($currentPath[$currentLevel + 1], $currentPathWildcard[$currentLevel+1], $stack[$currentLevel+1]);
|
||||
}
|
||||
if (
|
||||
(
|
||||
@ -230,7 +229,7 @@ class Parser implements \IteratorAggregate, PositionAware
|
||||
! $objectKeyExpected
|
||||
&& (
|
||||
($currentLevel === $iteratorLevel && $isValue)
|
||||
|| ($currentLevel+1 === $iteratorLevel && ($tokenType | 3) === 3) // 3 = self::SCALAR_VALUE
|
||||
|| ($currentLevel + 1 === $iteratorLevel && ($tokenType | 3) === 3) // 3 = self::SCALAR_VALUE
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -254,7 +253,7 @@ class Parser implements \IteratorAggregate, PositionAware
|
||||
$currentPathChanged = true;
|
||||
$currentPath[$currentLevel] = $keyResult->getValue();
|
||||
$currentPathWildcard[$currentLevel] = $keyResult->getValue();
|
||||
unset($keyResult, $currentPath[$currentLevel+1], $currentPathWildcard[$currentLevel+1]);
|
||||
unset($keyResult, $currentPath[$currentLevel + 1], $currentPathWildcard[$currentLevel+1]);
|
||||
}
|
||||
continue 2; // a valid json chunk is not completed yet
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ namespace JsonMachine;
|
||||
interface PositionAware
|
||||
{
|
||||
/**
|
||||
* Returns a number of processed bytes from the beginning
|
||||
* Returns a number of processed bytes from the beginning.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
@ -14,12 +14,12 @@ class StreamChunks implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* @param resource $stream
|
||||
* @param int $chunkSize
|
||||
* @param int $chunkSize
|
||||
*/
|
||||
public function __construct($stream, $chunkSize = 1024 * 8)
|
||||
{
|
||||
if (! is_resource($stream) || get_resource_type($stream) !== 'stream') {
|
||||
throw new InvalidArgumentException("Argument \$stream must be a valid stream resource.");
|
||||
throw new InvalidArgumentException('Argument $stream must be a valid stream resource.');
|
||||
}
|
||||
$this->stream = $stream;
|
||||
$this->chunkSize = $chunkSize;
|
||||
|
@ -12,7 +12,7 @@ class StringChunks implements \IteratorAggregate
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param int $chunkSize
|
||||
* @param int $chunkSize
|
||||
*/
|
||||
public function __construct($string, $chunkSize = 1024 * 8)
|
||||
{
|
||||
@ -27,7 +27,7 @@ class StringChunks implements \IteratorAggregate
|
||||
public function getIterator()
|
||||
{
|
||||
$len = strlen($this->string);
|
||||
for ($i=0; $i<$len; $i += $this->chunkSize) {
|
||||
for ($i = 0; $i < $len; $i += $this->chunkSize) {
|
||||
yield substr($this->string, $i, $this->chunkSize);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
$client = new \GuzzleHttp\Client();
|
||||
$response = $client->request('GET', 'https://httpbin.org/anything?key=value');
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
use JsonMachine\Items;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
ini_set('memory_limit', 128*1024*1024);
|
||||
ini_set('memory_limit', 128 * 1024 * 1024);
|
||||
|
||||
function dummy()
|
||||
{
|
||||
$i = 0;
|
||||
$string = file_get_contents(__DIR__ . '/../../test/performance/twitter_example_0.json');
|
||||
$item = '[' . str_repeat($string.",", 400).$string . ']';
|
||||
$string = file_get_contents(__DIR__.'/../../test/performance/twitter_example_0.json');
|
||||
$item = '['.str_repeat($string.',', 400).$string.']';
|
||||
var_dump(strlen($item));
|
||||
|
||||
yield '[';
|
||||
@ -27,7 +27,7 @@ $items = Items::fromIterable(dummy());
|
||||
$previousReport = '';
|
||||
foreach ($items as $i => $item) {
|
||||
$report = memory_get_peak_usage()
|
||||
.":".memory_get_peak_usage(true)
|
||||
.':'.memory_get_peak_usage(true)
|
||||
;
|
||||
|
||||
if ($report !== $previousReport) {
|
||||
|
@ -4,7 +4,7 @@ use JsonMachine\Items;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
function httpClientChunks(ResponseStreamInterface $responseStream)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ class FileChunksTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testGeneratorYieldsStringChunks($chunkSize, array $expectedResult)
|
||||
{
|
||||
$fileChunks = new FileChunks(__DIR__ . '/ItemsTest.json', $chunkSize);
|
||||
$fileChunks = new FileChunks(__DIR__.'/ItemsTest.json', $chunkSize);
|
||||
$result = iterator_to_array($fileChunks);
|
||||
|
||||
$this->assertSame($expectedResult, $result);
|
||||
@ -20,9 +20,9 @@ class FileChunksTest extends \PHPUnit_Framework_TestCase
|
||||
public function data_testGeneratorYieldsFileChunks()
|
||||
{
|
||||
return [
|
||||
[5, ['{"pat','h": {','"key"',':"val','ue"}}', "\n"]],
|
||||
[6, ['{"path','": {"k','ey":"v','alue"}','}' . "\n"]],
|
||||
[1024, ['{"path": {"key":"value"}}' . "\n"]],
|
||||
[5, ['{"pat', 'h": {', '"key"', ':"val', 'ue"}}', "\n"]],
|
||||
[6, ['{"path', '": {"k', 'ey":"v', 'alue"}', '}'."\n"]],
|
||||
[1024, ['{"path": {"key":"value"}}'."\n"]],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace JsonMachineTest;
|
||||
|
||||
use JsonMachine\JsonDecoder\PassThruDecoder;
|
||||
use JsonMachine\Items;
|
||||
use JsonMachine\JsonDecoder\PassThruDecoder;
|
||||
|
||||
class ItemsTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -18,7 +18,7 @@ class ItemsTest extends \PHPUnit_Framework_TestCase
|
||||
'pointer' => $args[1],
|
||||
'decoder' => $args[2],
|
||||
'debug' => $args[3],
|
||||
]
|
||||
],
|
||||
]);
|
||||
$this->assertSame($expected, iterator_to_array($iterator));
|
||||
}
|
||||
@ -27,7 +27,7 @@ class ItemsTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$iterator = Items::fromString('{"path": {"key":"value"}}');
|
||||
foreach ($iterator as $item) {
|
||||
$this->assertEquals((object)['key' => 'value'], $item);
|
||||
$this->assertEquals((object) ['key' => 'value'], $item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,13 +41,13 @@ class ItemsTest extends \PHPUnit_Framework_TestCase
|
||||
foreach ([
|
||||
[$extJsonResult, 'fromStream', fopen('data://text/plain,{"path": {"key":"value"}}', 'r'), '/path', null, $debug],
|
||||
[$extJsonResult, 'fromString', '{"path": {"key":"value"}}', '/path', null, $debug],
|
||||
[$extJsonResult, 'fromFile', __DIR__ . '/ItemsTest.json', '/path', null, $debug],
|
||||
[$extJsonResult, 'fromFile', __DIR__.'/ItemsTest.json', '/path', null, $debug],
|
||||
[$extJsonResult, 'fromIterable', ['{"path": {"key', '":"value"}}'], '/path', null, $debug],
|
||||
[$extJsonResult, 'fromIterable', new \ArrayIterator(['{"path": {"key', '":"value"}}']), '/path', null, $debug],
|
||||
|
||||
[$passThruResult, 'fromStream', fopen('data://text/plain,{"path": {"key":"value"}}', 'r'), '/path', $ptDecoder, $debug],
|
||||
[$passThruResult, 'fromString', '{"path": {"key":"value"}}', '/path', $ptDecoder, $debug],
|
||||
[$passThruResult, 'fromFile', __DIR__ . '/ItemsTest.json', '/path', $ptDecoder, $debug],
|
||||
[$passThruResult, 'fromFile', __DIR__.'/ItemsTest.json', '/path', $ptDecoder, $debug],
|
||||
[$passThruResult, 'fromIterable', ['{"path": {"key', '":"value"}}'], '/path', $ptDecoder, $debug],
|
||||
[$passThruResult, 'fromIterable', new \ArrayIterator(['{"path": {"key', '":"value"}}']), '/path', $ptDecoder, $debug],
|
||||
] as $case) {
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
namespace JsonMachineTest\JsonDecoder;
|
||||
|
||||
use JsonMachine\Items;
|
||||
use JsonMachine\JsonDecoder\DecodingError;
|
||||
use JsonMachine\JsonDecoder\DecodingResult;
|
||||
use JsonMachine\JsonDecoder\ErrorWrappingDecoder;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
use JsonMachine\Items;
|
||||
use JsonMachine\JsonDecoder\InvalidResult;
|
||||
use JsonMachine\JsonDecoder\ValidResult;
|
||||
use PHPUnit_Framework_TestCase;
|
||||
@ -15,7 +14,6 @@ class ErrorWrappingDecoderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider data_testTrueFalseMatrix
|
||||
* @param array $case
|
||||
*/
|
||||
public function testTrueFalseMatrix(array $case)
|
||||
{
|
||||
@ -42,41 +40,41 @@ class ErrorWrappingDecoderTest extends PHPUnit_Framework_TestCase
|
||||
[
|
||||
[
|
||||
'decodeValue' => $notOkResult,
|
||||
'decodeKey' => $notOkResult,
|
||||
'decodeKey' => $notOkResult,
|
||||
'wrappedDecodeValue' => $wrappedNotOkResult,
|
||||
'wrappedDecodeKey' => $wrappedNotOkResult,
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'decodeValue' => $notOkResult,
|
||||
'decodeKey' => $okResult,
|
||||
'decodeKey' => $okResult,
|
||||
'wrappedDecodeValue' => $wrappedNotOkResult,
|
||||
'wrappedDecodeKey' => $wrappedOkResult,
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'decodeValue' => $okResult,
|
||||
'decodeKey' => $notOkResult,
|
||||
'decodeKey' => $notOkResult,
|
||||
'wrappedDecodeValue' => $wrappedOkResult,
|
||||
'wrappedDecodeKey' => $wrappedNotOkResult,
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'decodeValue' => $okResult,
|
||||
'decodeKey' => $okResult,
|
||||
'decodeKey' => $okResult,
|
||||
'wrappedDecodeValue' => $wrappedOkResult,
|
||||
'wrappedDecodeKey' => $wrappedOkResult,
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testCatchesErrorInsideIteratedJsonChunk()
|
||||
{
|
||||
$json = /** @lang JSON */ '
|
||||
$json = /* @lang JSON */ '
|
||||
{
|
||||
"results": [
|
||||
{"correct": "correct"},
|
||||
|
@ -17,26 +17,26 @@ class ExtJsonDecodersTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
$defaultDecoder = new $className();
|
||||
$defaultResult = $defaultDecoder->$methodName($json);
|
||||
$this->assertTrue("object" === gettype($defaultResult->getValue()));
|
||||
$this->assertFalse("string" === gettype($defaultResult->getValue()->bigint));
|
||||
$this->assertSame([["deeper"]], $defaultResult->getValue()->deep);
|
||||
$this->assertTrue('object' === gettype($defaultResult->getValue()));
|
||||
$this->assertFalse('string' === gettype($defaultResult->getValue()->bigint));
|
||||
$this->assertSame([['deeper']], $defaultResult->getValue()->deep);
|
||||
|
||||
$assocDecoder = new $className(true);
|
||||
$assocResult = $assocDecoder->$methodName($json);
|
||||
$this->assertTrue("array" === gettype($assocResult->getValue()));
|
||||
$this->assertTrue('array' === gettype($assocResult->getValue()));
|
||||
|
||||
$objDecoder = new $className(false);
|
||||
$objResult = $objDecoder->$methodName($json);
|
||||
$this->assertTrue("object" === gettype($objResult->getValue()));
|
||||
$this->assertTrue('object' === gettype($objResult->getValue()));
|
||||
|
||||
$depthDecoder = new $className(true, 1);
|
||||
$depthResult = $depthDecoder->$methodName($json);
|
||||
$this->assertFalse($depthResult->isOk());
|
||||
$this->assertSame("Maximum stack depth exceeded", $depthResult->getErrorMessage());
|
||||
$this->assertSame('Maximum stack depth exceeded', $depthResult->getErrorMessage());
|
||||
|
||||
$bigintDecoder = new $className(null, 1, JSON_BIGINT_AS_STRING);
|
||||
$bigintResult = $bigintDecoder->$methodName("123123123123123123123");
|
||||
$this->assertSame("123123123123123123123", $bigintResult->getValue());
|
||||
$bigintResult = $bigintDecoder->$methodName('123123123123123123123');
|
||||
$this->assertSame('123123123123123123123', $bigintResult->getValue());
|
||||
}
|
||||
|
||||
public function dataPassesOptionsToJsonDecode()
|
||||
|
@ -4,7 +4,6 @@ namespace JsonMachineTest;
|
||||
|
||||
use JsonMachine\DebugLexer;
|
||||
use JsonMachine\Lexer;
|
||||
use JsonMachine\Exception;
|
||||
use JsonMachine\StreamChunks;
|
||||
use JsonMachine\StringChunks;
|
||||
|
||||
@ -38,7 +37,7 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGeneratesTokens($lexerClass)
|
||||
{
|
||||
$data = ['{}[],:null,"string" false:', 'true,1,100000,1.555{-56]"","\\""'];
|
||||
$expected = ['{','}','[',']',',',':','null',',','"string"','false',':','true',',','1',',','100000',',','1.555','{','-56',']','""',',','"\\""'];
|
||||
$expected = ['{', '}', '[', ']', ',', ':', 'null', ',', '"string"', 'false', ':', 'true', ',', '1', ',', '100000', ',', '1.555', '{', '-56', ']', '""', ',', '"\\""'];
|
||||
$this->assertEquals($expected, iterator_to_array(new $lexerClass(new \ArrayIterator($data))));
|
||||
}
|
||||
|
||||
@ -47,8 +46,8 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testWithBOM($lexerClass)
|
||||
{
|
||||
$data = ["\xEF\xBB\xBF" . '{}'];
|
||||
$expected = ['{','}'];
|
||||
$data = ["\xEF\xBB\xBF".'{}'];
|
||||
$expected = ['{', '}'];
|
||||
$this->assertEquals($expected, iterator_to_array(new $lexerClass(new \ArrayIterator($data))));
|
||||
}
|
||||
|
||||
@ -133,7 +132,7 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
'{', '"datafeed"', ':', '{', '"info"', ':', '{', '"category"', ':', '"Category name"', '}', ',',
|
||||
'"programs"', ':', '[', '{', '"program_info"', ':', '{', '"id"', ':', '"X0\\"\\\\"', ',', '"number"', ':',
|
||||
'123', ',', '"constant"', ':', 'false', '}', '}', ',', '{', '"program_info"', ':', '{', '"id"', ':',
|
||||
'"\b\f\n\r\t\u0020X1"', '}', '}', ']', '}', '}'
|
||||
'"\b\f\n\r\t\u0020X1"', '}', '}', ']', '}', '}',
|
||||
];
|
||||
|
||||
foreach (range(1, strlen($json)) as $chunkLength) {
|
||||
@ -156,12 +155,12 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
$i = 0;
|
||||
|
||||
foreach ($lexer as $token) {
|
||||
$i++;
|
||||
++$i;
|
||||
$expectedToken = array_shift($expectedTokens);
|
||||
|
||||
$this->assertEquals($expectedToken[0], $token, 'token failed with expected token #' . $i);
|
||||
$this->assertEquals($expectedToken[1], $lexer->getLine(), 'line failed with expected token #' . $i);
|
||||
$this->assertEquals($expectedToken[2], $lexer->getColumn(), 'column failed with expected token #' . $i);
|
||||
$this->assertEquals($expectedToken[0], $token, 'token failed with expected token #'.$i);
|
||||
$this->assertEquals($expectedToken[1], $lexer->getLine(), 'line failed with expected token #'.$i);
|
||||
$this->assertEquals($expectedToken[2], $lexer->getColumn(), 'column failed with expected token #'.$i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,21 +176,21 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
$i = 0;
|
||||
|
||||
foreach ($lexer as $token) {
|
||||
$i++;
|
||||
++$i;
|
||||
$expectedToken = array_shift($expectedTokens);
|
||||
|
||||
$this->assertEquals($expectedToken[0], $token, 'token failed with expected token #' . $i);
|
||||
$this->assertEquals(1, $lexer->getLine(), 'line failed with expected token #' . $i);
|
||||
$this->assertEquals(0, $lexer->getColumn(), 'column failed with expected token #' . $i);
|
||||
$this->assertEquals($expectedToken[0], $token, 'token failed with expected token #'.$i);
|
||||
$this->assertEquals(1, $lexer->getLine(), 'line failed with expected token #'.$i);
|
||||
$this->assertEquals(0, $lexer->getColumn(), 'column failed with expected token #'.$i);
|
||||
}
|
||||
}
|
||||
|
||||
public function dataProvidesLocationalData()
|
||||
{
|
||||
return [
|
||||
'cr new lines' => [__DIR__ . '/formatted-cr.json'],
|
||||
'lf new lines' => [__DIR__ . '/formatted-lf.json'],
|
||||
'crlf new lines' => [__DIR__ . '/formatted-crlf.json'],
|
||||
'cr new lines' => [__DIR__.'/formatted-cr.json'],
|
||||
'lf new lines' => [__DIR__.'/formatted-lf.json'],
|
||||
'crlf new lines' => [__DIR__.'/formatted-crlf.json'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -263,7 +262,7 @@ class LexerTest extends \PHPUnit_Framework_TestCase
|
||||
['"geo"', 18, 3],
|
||||
[':', 18, 8],
|
||||
['null', 18, 10],
|
||||
['}', 19, 1]
|
||||
['}', 19, 1],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use JsonMachine\Exception\PathNotFoundException;
|
||||
use JsonMachine\Exception\SyntaxError;
|
||||
use JsonMachine\Exception\UnexpectedEndSyntaxErrorException;
|
||||
use JsonMachine\JsonDecoder\ExtJsonDecoder;
|
||||
use JsonMachine\Items;
|
||||
use JsonMachine\Lexer;
|
||||
use JsonMachine\Parser;
|
||||
use JsonMachine\StringChunks;
|
||||
@ -16,9 +15,10 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider dataSyntax
|
||||
*
|
||||
* @param string $jsonPointer
|
||||
* @param string $json
|
||||
* @param array $expectedResult
|
||||
* @param array $expectedResult
|
||||
*/
|
||||
public function testSyntax($jsonPointer, $json, $expectedResult)
|
||||
{
|
||||
@ -34,38 +34,38 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
return [
|
||||
['', '{}', []],
|
||||
['', '{"a": "b"}', [['a'=>'b']]],
|
||||
['', '{"a":{"b":{"c":1}}}', [['a'=>['b'=>['c'=>1]]]]],
|
||||
['', '{"a": "b"}', [['a' => 'b']]],
|
||||
['', '{"a":{"b":{"c":1}}}', [['a' => ['b' => ['c' => 1]]]]],
|
||||
['', '[]', []],
|
||||
['', '[null,true,false,"a",0,1,42.5]', [[0=>null],[1=>true],[2=>false],[3=>"a"],[4=>0],[5=>1],[6=>42.5]]],
|
||||
['', '[{"c":1}]', [[['c'=>1]]]],
|
||||
['', '[{"c":1},"string",{"d":2},false]', [[0=>['c'=>1]],[1=>"string"],[2=>['d'=>2]],[3=>false]]],
|
||||
['', '[false,{"c":1},"string",{"d":2}]', [[0=>false],[1=>['c'=>1]],[2=>"string"],[3=>['d'=>2]]]],
|
||||
['', '[{"c":1,"d":2}]', [[['c'=>1, 'd'=>2]]]],
|
||||
['/', '{"":{"c":1,"d":2}}', [['c'=>1],['d'=>2]]],
|
||||
['/~0', '{"~":{"c":1,"d":2}}', [['c'=>1],['d'=>2]]],
|
||||
['/~1', '{"/":{"c":1,"d":2}}', [['c'=>1],['d'=>2]]],
|
||||
['/path', '{"path":{"c":1,"d":2}}', [['c'=>1],['d'=>2]]],
|
||||
['/path', '{"no":[null], "path":{"c":1,"d":2}}', [['c'=>1],['d'=>2]]],
|
||||
['/0', '[{"c":1,"d":2}, [null]]', [['c'=>1],['d'=>2]]],
|
||||
['/0/path', '[{"path":{"c":1,"d":2}}]', [['c'=>1],['d'=>2]]],
|
||||
['/1/path', '[[null], {"path":{"c":1,"d":2}}]', [['c'=>1],['d'=>2]]],
|
||||
['/path/0', '{"path":[{"c":1,"d":2}, [null]]}', [['c'=>1],['d'=>2]]],
|
||||
['/path/1', '{"path":[null,{"c":1,"d":2}, [null]]}', [['c'=>1],['d'=>2]]],
|
||||
['/path/to', '{"path":{"to":{"c":1,"d":2}}}', [['c'=>1],['d'=>2]]],
|
||||
['/path/after-vector', '{"path":{"array":[],"after-vector":{"c":1,"d":2}}}', [['c'=>1],['d'=>2]]],
|
||||
['/path/after-vector', '{"path":{"array":["item"],"after-vector":{"c":1,"d":2}}}', [['c'=>1],['d'=>2]]],
|
||||
['/path/after-vector', '{"path":{"object":{"item":null},"after-vector":{"c":1,"d":2}}}', [['c'=>1],['d'=>2]]],
|
||||
['/path/after-vectors', '{"path":{"array":[],"object":{},"after-vectors":{"c":1,"d":2}}}', [['c'=>1],['d'=>2]]],
|
||||
['/0/0', '[{"0":{"c":1,"d":2}}]', [['c'=>1],['d'=>2]]],
|
||||
['/1/1', '[0,{"1":{"c":1,"d":2}}]', [['c'=>1],['d'=>2]]],
|
||||
'PR-19-FIX' => ['/datafeed/programs/1', file_get_contents(__DIR__.'/PR-19-FIX.json'), [['program_info'=>['id'=>'X1']]]],
|
||||
'ISSUE-41-FIX' => ['/path', '{"path":[{"empty":{}},{"value":1}]}', [[["empty"=>[]]],[1=>["value"=>1]]]],
|
||||
['/-', '[{"one": 1,"two": 2},{"three": 3,"four": 4}]', [['one'=>1], ['two'=>2], ['three'=>3], ['four'=>4]]],
|
||||
['/zero/-', '{"zero":[{"one": 1,"two": 2},{"three": 3,"four": 4}]}', [['one'=>1], ['two'=>2], ['three'=>3], ['four'=>4]]],
|
||||
['/zero/-/three', '{"zero":[{"one": 1,"two": 2},{"three": 3,"four": 4}]}', [['three'=>3]]],
|
||||
'ISSUE-62#1' => ['/-/id', '[ {"id":125}, {"id":785}, {"id":459}, {"id":853} ]', [['id'=>125], ['id'=>785], ['id'=>459], ['id'=>853]]],
|
||||
'ISSUE-62#2' => ['/key/-/id', '{"key": [ {"id":125}, {"id":785}, {"id":459}, {"id":853} ]}', [['id'=>125], ['id'=>785], ['id'=>459], ['id'=>853]]],
|
||||
['', '[null,true,false,"a",0,1,42.5]', [[0 => null], [1 => true], [2 => false], [3 => 'a'], [4 => 0], [5 => 1], [6 => 42.5]]],
|
||||
['', '[{"c":1}]', [[['c' => 1]]]],
|
||||
['', '[{"c":1},"string",{"d":2},false]', [[0 => ['c' => 1]], [1 => 'string'], [2 => ['d' => 2]], [3 => false]]],
|
||||
['', '[false,{"c":1},"string",{"d":2}]', [[0 => false], [1 => ['c' => 1]], [2 => 'string'], [3 => ['d' => 2]]]],
|
||||
['', '[{"c":1,"d":2}]', [[['c' => 1, 'd' => 2]]]],
|
||||
['/', '{"":{"c":1,"d":2}}', [['c' => 1], ['d' => 2]]],
|
||||
['/~0', '{"~":{"c":1,"d":2}}', [['c' => 1], ['d' => 2]]],
|
||||
['/~1', '{"/":{"c":1,"d":2}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path', '{"path":{"c":1,"d":2}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path', '{"no":[null], "path":{"c":1,"d":2}}', [['c' => 1], ['d' => 2]]],
|
||||
['/0', '[{"c":1,"d":2}, [null]]', [['c' => 1], ['d' => 2]]],
|
||||
['/0/path', '[{"path":{"c":1,"d":2}}]', [['c' => 1], ['d' => 2]]],
|
||||
['/1/path', '[[null], {"path":{"c":1,"d":2}}]', [['c' => 1], ['d' => 2]]],
|
||||
['/path/0', '{"path":[{"c":1,"d":2}, [null]]}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/1', '{"path":[null,{"c":1,"d":2}, [null]]}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/to', '{"path":{"to":{"c":1,"d":2}}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/after-vector', '{"path":{"array":[],"after-vector":{"c":1,"d":2}}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/after-vector', '{"path":{"array":["item"],"after-vector":{"c":1,"d":2}}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/after-vector', '{"path":{"object":{"item":null},"after-vector":{"c":1,"d":2}}}', [['c' => 1], ['d' => 2]]],
|
||||
['/path/after-vectors', '{"path":{"array":[],"object":{},"after-vectors":{"c":1,"d":2}}}', [['c' => 1], ['d' => 2]]],
|
||||
['/0/0', '[{"0":{"c":1,"d":2}}]', [['c' => 1], ['d' => 2]]],
|
||||
['/1/1', '[0,{"1":{"c":1,"d":2}}]', [['c' => 1], ['d' => 2]]],
|
||||
'PR-19-FIX' => ['/datafeed/programs/1', file_get_contents(__DIR__.'/PR-19-FIX.json'), [['program_info' => ['id' => 'X1']]]],
|
||||
'ISSUE-41-FIX' => ['/path', '{"path":[{"empty":{}},{"value":1}]}', [[['empty' => []]], [1 => ['value' => 1]]]],
|
||||
['/-', '[{"one": 1,"two": 2},{"three": 3,"four": 4}]', [['one' => 1], ['two' => 2], ['three' => 3], ['four' => 4]]],
|
||||
['/zero/-', '{"zero":[{"one": 1,"two": 2},{"three": 3,"four": 4}]}', [['one' => 1], ['two' => 2], ['three' => 3], ['four' => 4]]],
|
||||
['/zero/-/three', '{"zero":[{"one": 1,"two": 2},{"three": 3,"four": 4}]}', [['three' => 3]]],
|
||||
'ISSUE-62#1' => ['/-/id', '[ {"id":125}, {"id":785}, {"id":459}, {"id":853} ]', [['id' => 125], ['id' => 785], ['id' => 459], ['id' => 853]]],
|
||||
'ISSUE-62#2' => ['/key/-/id', '{"key": [ {"id":125}, {"id":785}, {"id":459}, {"id":853} ]}', [['id' => 125], ['id' => 785], ['id' => 459], ['id' => 853]]],
|
||||
[
|
||||
['/meta_data', '/data/companies'],
|
||||
'{"meta_data": {"total_rows": 2},"data": {"type": "companies","companies": [{"id": "1","company": "Company 1"},{"id": "2","company": "Company 2"}]}}',
|
||||
@ -94,12 +94,12 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
['id'=>'2'],
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataThrowsOnNotFoundJsonPointer
|
||||
*
|
||||
* @param string $json
|
||||
* @param string $jsonPointer
|
||||
*/
|
||||
@ -114,17 +114,17 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
public function dataThrowsOnNotFoundJsonPointer()
|
||||
{
|
||||
return [
|
||||
"non existing pointer" => ['{}', '/not/found'],
|
||||
'non existing pointer' => ['{}', '/not/found'],
|
||||
"empty string should not match '0'" => ['{"0":[]}', '/'],
|
||||
"empty string should not match 0" => ['[[]]', '/'],
|
||||
"0 should not match empty string" => ['{"":[]}', '/0'],
|
||||
'empty string should not match 0' => ['[[]]', '/'],
|
||||
'0 should not match empty string' => ['{"":[]}', '/0'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetJsonPointer
|
||||
*
|
||||
* @param string $jsonPointer
|
||||
* @param array $expectedJsonPointer
|
||||
*/
|
||||
public function testGetJsonPointerPath($jsonPointer, array $expectedJsonPointer)
|
||||
{
|
||||
@ -146,6 +146,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider dataThrowsOnMalformedJsonPointer
|
||||
*
|
||||
* @param string $jsonPointer
|
||||
*/
|
||||
public function testThrowsOnMalformedJsonPointer($jsonPointer)
|
||||
@ -167,6 +168,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @dataProvider dataSyntaxError
|
||||
*
|
||||
* @param string $malformedJson
|
||||
*/
|
||||
public function testSyntaxError($malformedJson)
|
||||
@ -198,12 +200,13 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
['["string",,"string"]'],
|
||||
['["string","string",]'],
|
||||
['["string",1eeee1]'],
|
||||
['{"key\u000Z": "non hex key"}']
|
||||
['{"key\u000Z": "non hex key"}'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataUnexpectedEndError
|
||||
*
|
||||
* @param string $malformedJson
|
||||
*/
|
||||
public function testUnexpectedEndError($malformedJson)
|
||||
@ -231,7 +234,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
['{"string":["string","string"]'],
|
||||
['{"string":["string","string"'],
|
||||
['{"string":["string","string",'],
|
||||
['{"string":["string","string","str']
|
||||
['{"string":["string","string","str'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -272,7 +275,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
';
|
||||
|
||||
$parser = $this->createParser($json, '/result');
|
||||
$this->assertSame(["result" => "one"], iterator_to_array($parser));
|
||||
$this->assertSame(['result' => 'one'], iterator_to_array($parser));
|
||||
}
|
||||
|
||||
public function testGeneratorYieldsNestedValues()
|
||||
@ -342,7 +345,7 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
||||
$items = new Parser(new Lexer(new StringChunks('[{"key": "value"}]')));
|
||||
|
||||
foreach ($items as $item) {
|
||||
$this->assertEquals((object)['key' => 'value'], $item);
|
||||
$this->assertEquals((object) ['key' => 'value'], $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
if (! class_exists('PHPUnit_Framework_TestCase')) {
|
||||
class_alias(\PHPUnit\Framework\TestCase::class, 'PHPUnit_Framework_TestCase');
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use JsonMachine\Items;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
if (in_array('xdebug', get_loaded_extensions())) {
|
||||
trigger_error('Xdebug enabled. Results may be affected.', E_USER_WARNING);
|
||||
@ -29,21 +29,21 @@ $decoders = [
|
||||
];
|
||||
|
||||
$tmpJsonFileName = createBigJsonFile();
|
||||
$fileSizeMb = (filesize($tmpJsonFileName)/1024/1024);
|
||||
echo "File size: " . round($fileSizeMb, 2)," MB".PHP_EOL;
|
||||
$fileSizeMb = (filesize($tmpJsonFileName) / 1024 / 1024);
|
||||
echo 'File size: '.round($fileSizeMb, 2),' MB'.PHP_EOL;
|
||||
foreach ($decoders as $name => $decoder) {
|
||||
$start = microtime(true);
|
||||
$result = $decoder($tmpJsonFileName);
|
||||
if (! $result instanceof \Traversable && ! is_array($result)) {
|
||||
$textResult = "Decoding error";
|
||||
$textResult = 'Decoding error';
|
||||
} else {
|
||||
foreach ($result as $key => $item) {
|
||||
}
|
||||
$time = microtime(true) - $start;
|
||||
$textResult = round($fileSizeMb/$time, 2) . ' MB/s';
|
||||
$textResult = round($fileSizeMb / $time, 2).' MB/s';
|
||||
}
|
||||
|
||||
echo str_pad($name.": ", 37, '.')." $textResult".PHP_EOL;
|
||||
echo str_pad($name.': ', 37, '.')." $textResult".PHP_EOL;
|
||||
}
|
||||
@unlink($tmpJsonFileName);
|
||||
|
||||
@ -53,12 +53,13 @@ function createBigJsonFile()
|
||||
$f = fopen($tmpJson, 'w');
|
||||
$separator = '';
|
||||
fputs($f, '[');
|
||||
for ($i=0; $i<6000; $i++) {
|
||||
for ($i = 0; $i < 6000; ++$i) {
|
||||
fputs($f, $separator);
|
||||
fputs($f, file_get_contents(__DIR__.'/twitter_example_'. ($i%2) .'.json'));
|
||||
fputs($f, file_get_contents(__DIR__.'/twitter_example_'.($i % 2).'.json'));
|
||||
$separator = ",\n\n";
|
||||
}
|
||||
fputs($f, ']');
|
||||
fclose($f);
|
||||
|
||||
return $tmpJson;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user