Skip to content

Commit 602f46e

Browse files
committed
performance improvements
1 parent 2128f9d commit 602f46e

File tree

12 files changed

+86
-101
lines changed

12 files changed

+86
-101
lines changed

.travis.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
sudo: false
22
language: php
33

4+
cache:
5+
directories:
6+
- $HOME/.composer/cache
7+
48
matrix:
59
fast_finish: true
610
include:
711
- php: 5.3
812
- php: 5.4
913
- php: 5.5
1014
- php: 5.6
15+
- php: 7.0
1116
env: WITH_COVERAGE=true
12-
- php: 7
17+
- php: 7.1
18+
- php: 'nightly'
1319
- php: hhvm
20+
allow_failures:
21+
- php: 'nightly'
1422

1523
before_install:
16-
- if [[ "$WITH_COVERAGE" != "true" && "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi
24+
- if [[ "$WITH_COVERAGE" != "true" && "$TRAVIS_PHP_VERSION" != "hhvm" && "$TRAVIS_PHP_VERSION" != "nightly" && "$TRAVIS_PHP_VERSION" != "7.1" ]]; then phpenv config-rm xdebug.ini; fi
1725
- composer selfupdate
1826

1927
install:
20-
- travis_retry composer install --no-interaction --prefer-source
28+
- travis_retry composer install --no-interaction --prefer-dist
2129

2230
script:
23-
- if [[ "$WITH_COVERAGE" == "true" ]]; then vendor/bin/phpunit --coverage-text; else vendor/bin/phpunit; fi
31+
- if [[ "$WITH_COVERAGE" == "true" ]]; then composer coverage; else composer test; fi

composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,9 @@
5454
"branch-alias": {
5555
"dev-master": "3.0.x-dev"
5656
}
57+
},
58+
"scripts": {
59+
"test" : "vendor/bin/phpunit",
60+
"coverage" : "vendor/bin/phpunit --coverage-text"
5761
}
5862
}

src/JsonSchema/Constraints/CollectionConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ protected function validateItems($value, $schema = null, JsonPointer $path = nul
106106
// Treat when we have more schema definitions than values, not for empty arrays
107107
if (count($value) > 0) {
108108
for ($k = count($value); $k < count($schema->items); $k++) {
109-
$this->checkUndefined(new UndefinedConstraint(), $schema->items[$k], $path, $k);
109+
$this->checkUndefined($this->getFactory()->createInstanceFor('undefined'), $schema->items[$k], $path, $k);
110110
}
111111
}
112112
}

src/JsonSchema/Constraints/Constraint.php

Lines changed: 17 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -22,48 +22,23 @@
2222
*/
2323
abstract class Constraint implements ConstraintInterface
2424
{
25-
protected $schemaStorage;
26-
protected $checkMode = self::CHECK_MODE_NORMAL;
27-
protected $uriRetriever;
2825
protected $errors = array();
2926
protected $inlineSchemaProperty = '$schema';
3027

3128
const CHECK_MODE_NORMAL = 1;
3229
const CHECK_MODE_TYPE_CAST = 2;
3330

3431
/**
35-
* @var null|Factory
32+
* @var Factory
3633
*/
3734
private $factory;
3835

3936
/**
40-
* @param int $checkMode
41-
* @param SchemaStorage $schemaStorage
42-
* @param UriRetrieverInterface $uriRetriever
4337
* @param Factory $factory
4438
*/
45-
public function __construct(
46-
$checkMode = self::CHECK_MODE_NORMAL,
47-
SchemaStorage $schemaStorage = null,
48-
UriRetrieverInterface $uriRetriever = null,
49-
Factory $factory = null
50-
) {
51-
$this->checkMode = $checkMode;
52-
$this->uriRetriever = $uriRetriever;
53-
$this->factory = $factory;
54-
$this->schemaStorage = $schemaStorage;
55-
}
56-
57-
/**
58-
* @return UriRetrieverInterface $uriRetriever
59-
*/
60-
public function getUriRetriever()
39+
public function __construct(Factory $factory = null)
6140
{
62-
if (is_null($this->uriRetriever)) {
63-
$this->setUriRetriever(new UriRetriever);
64-
}
65-
66-
return $this->uriRetriever;
41+
$this->factory = $factory ? : $this->getFactory();
6742
}
6843

6944
/**
@@ -72,32 +47,12 @@ public function getUriRetriever()
7247
public function getFactory()
7348
{
7449
if (!$this->factory) {
75-
$this->factory = new Factory($this->getSchemaStorage(), $this->getUriRetriever(), $this->checkMode);
50+
$this->factory = new Factory();
7651
}
7752

7853
return $this->factory;
7954
}
8055

81-
/**
82-
* @return SchemaStorage
83-
*/
84-
public function getSchemaStorage()
85-
{
86-
if (is_null($this->schemaStorage)) {
87-
$this->schemaStorage = new SchemaStorage($this->getUriRetriever());
88-
}
89-
90-
return $this->schemaStorage;
91-
}
92-
93-
/**
94-
* @param UriRetrieverInterface $uriRetriever
95-
*/
96-
public function setUriRetriever(UriRetrieverInterface $uriRetriever)
97-
{
98-
$this->uriRetriever = $uriRetriever;
99-
}
100-
10156
/**
10257
* {@inheritDoc}
10358
*/
@@ -123,7 +78,9 @@ public function addError(JsonPointer $path = null, $message, $constraint='', arr
12378
*/
12479
public function addErrors(array $errors)
12580
{
126-
$this->errors = array_merge($this->errors, $errors);
81+
if ($errors) {
82+
$this->errors = array_merge($this->errors, $errors);
83+
}
12784
}
12885

12986
/**
@@ -181,7 +138,7 @@ protected function incrementPath(JsonPointer $path = null, $i)
181138
*/
182139
protected function checkArray($value, $schema = null, JsonPointer $path = null, $i = null)
183140
{
184-
$validator = $this->getFactory()->createInstanceFor('collection');
141+
$validator = $this->factory->createInstanceFor('collection');
185142
$validator->check($value, $schema, $path, $i);
186143

187144
$this->addErrors($validator->getErrors());
@@ -198,7 +155,7 @@ protected function checkArray($value, $schema = null, JsonPointer $path = null,
198155
*/
199156
protected function checkObject($value, $schema = null, JsonPointer $path = null, $i = null, $patternProperties = null)
200157
{
201-
$validator = $this->getFactory()->createInstanceFor('object');
158+
$validator = $this->factory->createInstanceFor('object');
202159
$validator->check($value, $schema, $path, $i, $patternProperties);
203160

204161
$this->addErrors($validator->getErrors());
@@ -214,7 +171,7 @@ protected function checkObject($value, $schema = null, JsonPointer $path = null,
214171
*/
215172
protected function checkType($value, $schema = null, JsonPointer $path = null, $i = null)
216173
{
217-
$validator = $this->getFactory()->createInstanceFor('type');
174+
$validator = $this->factory->createInstanceFor('type');
218175
$validator->check($value, $schema, $path, $i);
219176

220177
$this->addErrors($validator->getErrors());
@@ -230,8 +187,8 @@ protected function checkType($value, $schema = null, JsonPointer $path = null, $
230187
*/
231188
protected function checkUndefined($value, $schema = null, JsonPointer $path = null, $i = null)
232189
{
233-
$validator = $this->getFactory()->createInstanceFor('undefined');
234-
$validator->check($value, $this->schemaStorage->resolveRefSchema($schema), $path, $i);
190+
$validator = $this->factory->createInstanceFor('undefined');
191+
$validator->check($value, $this->getFactory()->getSchemaStorage()->resolveRefSchema($schema), $path, $i);
235192

236193
$this->addErrors($validator->getErrors());
237194
}
@@ -246,7 +203,7 @@ protected function checkUndefined($value, $schema = null, JsonPointer $path = nu
246203
*/
247204
protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null)
248205
{
249-
$validator = $this->getFactory()->createInstanceFor('string');
206+
$validator = $this->factory->createInstanceFor('string');
250207
$validator->check($value, $schema, $path, $i);
251208

252209
$this->addErrors($validator->getErrors());
@@ -262,7 +219,7 @@ protected function checkString($value, $schema = null, JsonPointer $path = null,
262219
*/
263220
protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null)
264221
{
265-
$validator = $this->getFactory()->createInstanceFor('number');
222+
$validator = $this->factory->createInstanceFor('number');
266223
$validator->check($value, $schema, $path, $i);
267224

268225
$this->addErrors($validator->getErrors());
@@ -278,7 +235,7 @@ protected function checkNumber($value, $schema = null, JsonPointer $path = null,
278235
*/
279236
protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null)
280237
{
281-
$validator = $this->getFactory()->createInstanceFor('enum');
238+
$validator = $this->factory->createInstanceFor('enum');
282239
$validator->check($value, $schema, $path, $i);
283240

284241
$this->addErrors($validator->getErrors());
@@ -294,7 +251,7 @@ protected function checkEnum($value, $schema = null, JsonPointer $path = null, $
294251
*/
295252
protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null)
296253
{
297-
$validator = $this->getFactory()->createInstanceFor('format');
254+
$validator = $this->factory->createInstanceFor('format');
298255
$validator->check($value, $schema, $path, $i);
299256

300257
$this->addErrors($validator->getErrors());
@@ -307,7 +264,7 @@ protected function checkFormat($value, $schema = null, JsonPointer $path = null,
307264
*/
308265
protected function getTypeCheck()
309266
{
310-
return $this->getFactory()->getTypeCheck();
267+
return $this->factory->getTypeCheck();
311268
}
312269

313270
/**

src/JsonSchema/Constraints/EnumConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function check($element, $schema = null, JsonPointer $path = null, $i = n
3232

3333
foreach ($schema->enum as $enum) {
3434
$enumType = gettype($enum);
35-
if ($this->checkMode === self::CHECK_MODE_TYPE_CAST && $type == "array" && $enumType == "object") {
35+
if ($this->getFactory()->getCheckMode() === self::CHECK_MODE_TYPE_CAST && $type == "array" && $enumType == "object") {
3636
if ((object)$element == $enum) {
3737
return;
3838
}

src/JsonSchema/Constraints/Factory.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,22 @@ public function setConstraintClass($name, $class)
128128
*/
129129
public function createInstanceFor($constraintName)
130130
{
131-
if (array_key_exists($constraintName, $this->constraintMap)) {
132-
if (!isset($this->instanceCache[$constraintName])) {
133-
$this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName](
134-
$this->checkMode,
135-
$this->schemaStorage,
136-
$this->uriRetriever,
137-
$this
138-
);
139-
}
140-
return clone $this->instanceCache[$constraintName];
131+
if (!isset($this->constraintMap[$constraintName])) {
132+
throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
141133
}
142-
throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
134+
135+
if (!isset($this->instanceCache[$constraintName])) {
136+
$this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this);
137+
}
138+
139+
return clone $this->instanceCache[$constraintName];
140+
}
141+
142+
/**
143+
* @return int
144+
*/
145+
public function getCheckMode()
146+
{
147+
return $this->checkMode;
143148
}
144149
}

src/JsonSchema/Constraints/ObjectConstraint.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function validatePatternProperties($element, JsonPointer $path = null, $p
8282
public function validateElement($element, $matches, $objectDefinition = null, JsonPointer $path = null, $additionalProp = null)
8383
{
8484
$this->validateMinMaxConstraint($element, $objectDefinition, $path);
85+
8586
foreach ($element as $i => $value) {
8687
$definition = $this->getProperty($objectDefinition, $i);
8788

@@ -105,7 +106,7 @@ public function validateElement($element, $matches, $objectDefinition = null, Js
105106
$this->addError($path, "The presence of the property " . $i . " requires that " . $require . " also be present", 'requires');
106107
}
107108

108-
$property = $this->getProperty($element, $i, new UndefinedConstraint());
109+
$property = $this->getProperty($element, $i, $this->getFactory()->createInstanceFor('undefined'));
109110
if (is_object($property)) {
110111
$this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path);
111112
}
@@ -117,12 +118,14 @@ public function validateElement($element, $matches, $objectDefinition = null, Js
117118
*
118119
* @param \stdClass $element Element to validate
119120
* @param \stdClass $objectDefinition ObjectConstraint definition
120-
* @param JsoinPointer|null $path Path?
121+
* @param JsonPointer|null $path Path?
121122
*/
122123
public function validateDefinition($element, $objectDefinition = null, JsonPointer $path = null)
123124
{
125+
$undefinedConstraint = $this->getFactory()->createInstanceFor('undefined');
126+
124127
foreach ($objectDefinition as $i => $value) {
125-
$property = $this->getProperty($element, $i, $this->getFactory()->createInstanceFor('undefined'));
128+
$property = $this->getProperty($element, $i, $undefinedConstraint);
126129
$definition = $this->getProperty($objectDefinition, $i);
127130

128131
if (is_object($definition)) {
@@ -143,10 +146,10 @@ public function validateDefinition($element, $objectDefinition = null, JsonPoint
143146
*/
144147
protected function getProperty($element, $property, $fallback = null)
145148
{
146-
if (is_array($element) /*$this->checkMode == self::CHECK_MODE_TYPE_CAST*/) {
147-
return array_key_exists($property, $element) ? $element[$property] : $fallback;
148-
} elseif (is_object($element)) {
149-
return property_exists($element, $property) ? $element->$property : $fallback;
149+
if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element)) /*$this->checkMode == self::CHECK_MODE_TYPE_CAST*/) {
150+
return $element[$property];
151+
} elseif (is_object($element) && property_exists($element, $property)) {
152+
return $element->$property;
150153
}
151154

152155
return $fallback;

src/JsonSchema/Constraints/UndefinedConstraint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ protected function validateDependencies($value, $dependencies, JsonPointer $path
267267
protected function validateUri($schema, $schemaUri = null)
268268
{
269269
$resolver = new UriResolver();
270-
$retriever = $this->getUriRetriever();
270+
$retriever = $this->getFactory()->getUriRetriever();
271271

272272
$jsonSchema = null;
273273
if ($resolver->isValid($schemaUri)) {

src/JsonSchema/Validator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
namespace JsonSchema;
1111

12-
use JsonSchema\Constraints\SchemaConstraint;
1312
use JsonSchema\Constraints\Constraint;
1413
use JsonSchema\Entity\JsonPointer;
1514

tests/Constraints/BaseTestCase.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace JsonSchema\Tests\Constraints;
1111

1212
use JsonSchema\Constraints\Constraint;
13+
use JsonSchema\Constraints\Factory;
1314
use JsonSchema\SchemaStorage;
1415
use JsonSchema\Uri\UriResolver;
1516
use JsonSchema\Validator;
@@ -36,7 +37,7 @@ public function testInvalidCases($input, $schema, $checkMode = Constraint::CHECK
3637
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema)));
3738
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
3839

39-
$validator = new Validator($checkMode, $schemaStorage);
40+
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
4041
$validator->check(json_decode($input), $schema);
4142

4243
if (array() !== $errors) {
@@ -58,7 +59,7 @@ public function testInvalidCasesUsingAssoc($input, $schema, $checkMode = Constra
5859
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema)));
5960
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
6061

61-
$validator = new Validator($checkMode, $schemaStorage);
62+
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
6263
$validator->check(json_decode($input, true), $schema);
6364

6465
if (array() !== $errors) {
@@ -75,7 +76,7 @@ public function testValidCases($input, $schema, $checkMode = Constraint::CHECK_M
7576
$schemaStorage = new SchemaStorage($this->getUriRetrieverMock(json_decode($schema)));
7677
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
7778

78-
$validator = new Validator($checkMode, $schemaStorage);
79+
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
7980
$validator->check(json_decode($input), $schema);
8081

8182
$this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true));
@@ -95,7 +96,7 @@ public function testValidCasesUsingAssoc($input, $schema, $checkMode = Constrain
9596
$schema = $schemaStorage->getSchema('http://www.my-domain.com/schema.json');
9697

9798
$value = json_decode($input, true);
98-
$validator = new Validator($checkMode, $schemaStorage);
99+
$validator = new Validator(new Factory($schemaStorage, null, $checkMode));
99100

100101
$validator->check($value, $schema);
101102
$this->assertTrue($validator->isValid(), print_r($validator->getErrors(), true));
@@ -142,6 +143,7 @@ private function getUriRetrieverMock($schema)
142143
$uriRetriever->retrieve('http://www.my-domain.com/schema.json')
143144
->willReturn($schema)
144145
->shouldBeCalled();
146+
145147
$uriRetriever->retrieve(Argument::any())
146148
->will(function ($args) use ($jsonSchemaDraft03, $jsonSchemaDraft04, $relativeTestsRoot) {
147149
if ('http://json-schema.org/draft-03/schema' === $args[0]) {

0 commit comments

Comments
 (0)