This PR was merged into the 4.1-dev branch.
Discussion
----------
[Process] Allow writing portable "prepared" command lines
| Q | A
| ------------- | ---
| Branch? | 4.1
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #23778
| License | MIT
| Doc PR | symfony/symfony-docs#9295
This give the opportunity to create process commands that allow to changes only the values instead of changing the code.
Commits
-------
d1e4f489d1 [Process] Allow writing portable "prepared" command lines
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Serializer] add a constructor arguement to return csv always as collection
| Q | A
| ------------- | ---
| Branch? | 4.1
| Bug fix? | yes
| New feature? | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | #21616
| License | MIT
| Doc PR | TODO create a doc PR for the 3 ways of getting csv collection, or a single
Coding in the train again ;).
![img_9980](https://user-images.githubusercontent.com/3451634/33417042-f13063e4-d59f-11e7-8f30-143da768b1d7.JPG)
This is to be able to add a new behaviour to the csv encoder when passing the alwaysAsCollection context key, this will return a collection even if there is only one element.
Commits
-------
d19d05dc5d [Serializer] add a context key to return csv always as collection
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Serializer] add a context key to return always as collection for XmlEncoder
| Q | A
| ------------- | ---
| Branch? | 4.1
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | #25227
| License | MIT
| Doc PR |
This PR add a new `as_collection` context key in order to return always as a collection instead of returning a single elements when there are only one array.
there are only one PR for the CsvEncoder don't wanted to have only One PR containing the two changes. It feel better to have two PR that fix the behaviour on two different things. it's easy to review and to revert if it break something (which should not since we are testing the behaviour).
Commits
-------
adb428d314 [Serializer] add a context key to return always as collection for XmlEncoder
This PR was squashed before being merged into the 4.1-dev branch (closes#26140).
Discussion
----------
[Serializer] deserialize as a null when inner object cannot be created and type hint allows null
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
```php
class ObjectConstructorDummy
{
protected $foo;
public $bar;
private $baz;
public function __construct($foo, $bar, $baz)
{
$this->foo = $foo;
$this->bar = $bar;
$this->baz = $baz;
}
}
class DummyWithNullableConstructorObject
{
private $id;
private $inner;
public function __construct($id, ?ObjectConstructorDummy $inner)
{
$this->id = $id;
$this->inner = $inner;
}
public function getId()
{
return $this->id;
}
public function getInner()
{
return $this->inner;
}
}
```
Trying to deserialize to `DummyWithNullableConstructorObject` with the following data currently fails:
```php
[
'id' => 10,
'inner' => null
]
```
With this PR `DummyWithNullableConstructorObject ` would be constructed with `null` passed as `$inner` because of the type hint.
Commits
-------
2fe9eb1aba [Serializer] deserialize as a null when inner object cannot be created and type hint allows null
This PR was squashed before being merged into the 4.1-dev branch (closes#26213).
Discussion
----------
[FrameworkBundle] Add support to 307/308 HTTP status codes in RedirectController
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #26171
| License | MIT
| Doc PR |
With this PR `RedirectController` will allow to create redirections with use of 307/308 HTTP status codes together with 301/302. Related RFC documents:
* https://tools.ietf.org/html/rfc7231
* https://tools.ietf.org/html/rfc7538
Commits
-------
64fb5a5663 [FrameworkBundle] Add support to 307/308 HTTP status codes in RedirectController
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Routing] Fix same-prefix aggregation
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
The blog post on http://symfony.com/blog/new-in-symfony-4-1-fastest-php-router made me review the aggregation logic, and discover issues.
So now, instead of this:
```
.'|/(en|fr)/admin/post/?(*:82)'
.'|/(en|fr)/admin/post/new(*:166)'
.'|/(en|fr)/admin/post/(\\d+)(*:253)'
.'|/(en|fr)/admin/post/(\\d+)/edit(*:345)'
.'|/(en|fr)/admin/post/(\\d+)/delete(*:442)'
.'|/(en|fr)/blog/?(*:519)'
.'|/(en|fr)/blog/rss\\.xml(*:603)'
.'|/(en|fr)/blog/page/([^/]++)(*:694)'
.'|/(en|fr)/blog/posts/([^/]++)(*:784)'
.'|/(en|fr)/blog/comment/(\d+)/new(*:880)'
.'|/(en|fr)/blog/search(*:962)'
.'|/(en|fr)/login(*:1038)'
.'|/(en|fr)/logout(*:1116)'
.'|/(en|fr)?(*:1188)'
```
we generate this:
```
.'|/(en|fr)(?'
.'|/admin/post(?'
.'|/?(*:34)'
.'|/new(*:45)'
.'|/(\\d+)(?'
.'|(*:61)'
.'|/edit(*:73)'
.'|/delete(*:87)'
.')'
.')'
.'|/blog(?'
.'|/?(*:106)'
.'|/rss\\.xml(*:123)'
.'|/p(?'
.'|age/([^/]++)(*:148)'
.'|osts/([^/]++)(*:169)'
.')'
.'|/comments/(\\d+)/new(*:197)'
.'|/search(*:212)'
.')'
.'|/log(?'
.'|in(*:230)'
.'|out(*:241)'
.')'
.')'
.'|/(en|fr)?(*:260)'
```
This is not only another perf fix, but a real bug fix, as I found ordering issues.
Commits
-------
d514f819dc [Routing] Fix same-prefix aggregation
This PR was merged into the 4.1-dev branch.
Discussion
----------
Fix undiscoverablility of SymfonyTestsListenerForV7
| Q | A
| ------------- | ---
| Branch? | `3.4@dev` (and `4@dev`)
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | n/a
| Fixed tickets | n/a
| License | MIT
| Doc PR | n/a
As class is in wrong namespace, it's not discoverable by autoloader and during execution of aliasing we face following crash:
```
ker@dus:~/github/PHP-CS-Fixer λ vendor/bin/phpunit
Class 'Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV7' not found
```
Commits
-------
538b257 Fix undiscoverablility of SymfonyTestsListenerForV7
* 4.0:
[Serializer] optims and cleanup
do not mock the container builder in tests
[PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener
fix accessing request values
Avoid running the remove command without any packages
[Form] Add translations for Tagalog
* 3.4:
[Serializer] optims and cleanup
do not mock the container builder in tests
[PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener
fix accessing request values
Avoid running the remove command without any packages
[Form] Add translations for Tagalog
This PR was squashed before being merged into the 2.7 branch (closes#26141).
Discussion
----------
[Serializer] optims and cleanup
| Q | A
| ------------- | ---
| Branch? | 2.7 <!-- see below -->
| Bug fix? | no
| New feature? | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass? | yes
| Fixed tickets | n/a <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | n/a
Tiny optimizations and small code cleanup. The opcode triggering is especially useful in the hot path (normalizers and encoders) because it's a recursive process.
Commits
-------
8ee8387 [Serializer] optims and cleanup
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Validator] support protocolless urls validation
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #24287
| License | MIT
As specified in issue #24287 URL's starting with no protocol but with just `//` are valid URL's and should be accepted by the validator. This pull request fixes the regex used to validate URL's.
Commits
-------
d845406 [Validator] support protocolless urls validation
This PR was merged into the 3.4 branch.
Discussion
----------
do not mock the container builder in tests
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
Commits
-------
777acfb do not mock the container builder in tests
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Routing] Handle very large set of dynamic routes
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Follow up of #26059; allows handling very long lists of dynamic routes.
Allows running https://github.com/tyler-sommer/php-router-benchmark seamlessly.
BTW, here are the result of running this benchmark:
R3 extension is not loaded. Skipping initialization for "Worst-case matching" test using R3.
R3 extension is not loaded. Skipping initialization for "First route matching" test using R3.
## Worst-case matching
This benchmark matches the last route and unknown route. It generates a randomly prefixed and suffixed route in an attempt to thwart any optimization. 1,000 routes each with 9 arguments.
This benchmark consists of 10 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.
Test Name | Results | Time | + Interval | Change
--------- | ------- | ---- | ---------- | ------
Symfony4 - unknown route (1000 routes) | 995 | 0.0000085699 | +0.0000000000 | baseline
Symfony4 - last route (1000 routes) | 999 | 0.0000086754 | +0.0000001055 | 1% slower
FastRoute - unknown route (1000 routes) | 980 | 0.0000305154 | +0.0000219455 | 256% slower
FastRoute - last route (1000 routes) | 999 | 0.0000529922 | +0.0000444223 | 518% slower
Pux PHP - unknown route (1000 routes) | 972 | 0.0003162730 | +0.0003077032 | 3591% slower
Pux PHP - last route (1000 routes) | 999 | 0.0004376847 | +0.0004291148 | 5007% slower
Aura v2 - unknown route (1000 routes) | 976 | 0.0138277517 | +0.0138191818 | 161253% slower
Aura v2 - last route (1000 routes) | 989 | 0.0138914190 | +0.0138828491 | 161996% slower
## First route matching
This benchmark tests how quickly each router can match the first route. 1,000 routes each with 9 arguments.
This benchmark consists of 5 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.
Test Name | Results | Time | + Interval | Change
--------- | ------- | ---- | ---------- | ------
FastRoute - first route | 999 | 0.0000016928 | +0.0000000000 | baseline
Pux PHP - first route | 999 | 0.0000017381 | +0.0000000453 | 3% slower
Symfony4 - first route | 997 | 0.0000029818 | +0.0000012890 | 76% slower
Aura v2 - first route | 977 | 0.0000376436 | +0.0000359508 | 2124% slower
Commits
-------
ee8b201 [Routing] Handle very large set of dynamic routes
This PR was merged into the 3.4 branch.
Discussion
----------
[PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
Commits
-------
6c0e6af [PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener
This PR was merged into the 3.4 branch.
Discussion
----------
[PHPUnit bridge] Avoid running the remove command without any packages
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes/no
| Fixed tickets | n/a
| License | MIT
| Doc PR | n/a
As the exit code of the command was not checked, the failure was not breaking things, but it was still printing a confusing error message.
This does not apply to versions older than 3.4, as it was impossible to set `SYMFONY_PHPUNIT_REMOVE` to an empty string before (it was applying the default removing rules instead in such case)
Commits
-------
34d2781 Avoid running the remove command without any packages
This PR was merged into the 4.1-dev branch.
Discussion
----------
[DI] Top micro benchmarks
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
This makes Symfony rank 1st most of the time, 2nd within the margin error otherwise.
Follow up of https://github.com/kocsismate/php-di-container-benchmarks/pull/21
Commits
-------
3edf5f1 [DI] Top micro benchmarks
This PR was merged into the 2.7 branch.
Discussion
----------
created validator.tl.xlf for Form/Translations
| Q | A
| ------------- | ---
| Branch? | master / 2.7 up to 4.0 for bug fixes <!-- see below -->
| Bug fix? | no
| New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks? | no
| Deprecations? |no <!-- don't forget to update UPGRADE-*.md files -->
| Tests pass? | no
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!--highly recommended for new features-->
<!--
- Bug fixes must be submitted against the lowest branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too).
- Features and deprecations must be submitted against the master branch.
- Replace this comment by a description of what your PR is solving.
-->
Commits
-------
6d4e5e0 [Form] Add translations for Tagalog
This PR was merged into the 4.1-dev branch.
Discussion
----------
[Routing] Match 77.7x faster by compiling routes in one regexp
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Builds on top of #25961 and http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html to make routing 77.7x faster (measured when matching the last dynamic route of 400 static + 400 dynamic routes.)
More benchs welcomed.
- [x] check static routes first in a switch
- [x] group same-modifiers regexps
- [x] put condition-less routes in a static map, in a switch's "default"
- [x] match host+pathinfo at the same time
- [x] group same-host regexps in sub-patterns
- [x] consider the host to move more static routes in the static switch
- [x] move static single-route "case" to "default" by adding requirements to $routes
- [x] group same-static-prefix in sub-patterns
- [x] group consecutive same-regex in a single "case"
- [x] move dynamic single-route "case" to "default" by adding requirements to $routes
- [x] extract host variables from the main match and remove the current 2nd match
- [x] extend same-prefix grouping to placeholders
- [x] group same-suffix hosts together
Here is my benchmarking code:
```php
<?php
namespace Symfony\Component\Routing;
require 'vendor/autoload.php';
$routes = new RouteCollection();
for ($i = 0; $i < 400; ++$i) {
$routes->add('r'.$i, new Route('/abc'.$i));
$routes->add('f'.$i, new Route('/abc{foo}/'.$i));
}
$dumper = new Matcher\Dumper\PhpMatcherDumper($routes);
eval('?'.'>'.$dumper->dump());
$router = new \ProjectUrlMatcher(new RequestContext());
$i = 10000;
$s = microtime(1);
while (--$i) {
$router->match('/abcdef/399');
}
echo 'Symfony: ', 1000 * (microtime(1) - $s), "\n";
namespace FastRoute;
$dispatcher = simpleDispatcher(function(RouteCollector $r) {
for ($i = 0; $i < 400; ++$i) {
$r->addRoute('GET', '/abc'.$i, 'r'.$i);
$r->addRoute('GET', '/abc{foo}/'.$i, 'f'.$i);
}
});
$i = 10000;
$s = microtime(1);
while (--$i) {
$dispatcher->dispatch('GET', '/abcdef/399');
}
echo 'FastRoute: ', 1000 * (microtime(1) - $s), "\n";
```
Commits
-------
f933f70483 [Routing] Match 77.7x faster by compiling routes in one regexp
* 4.0:
[Routing] Throw 405 instead of 404 when redirect is not possible
[Process] fix test case
Add security.tl.xlf to legacy directory
[Security][Validator] Add translations for Tagalog
fixed typo
Typo fix in security component lithuanian translation.
[TwigBundle][WebProfilerBundle] Fix JS collision
[Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder
* 3.4:
[Routing] Throw 405 instead of 404 when redirect is not possible
[Process] fix test case
Add security.tl.xlf to legacy directory
[Security][Validator] Add translations for Tagalog
fixed typo
Typo fix in security component lithuanian translation.
[TwigBundle][WebProfilerBundle] Fix JS collision
[Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder
* 2.8:
[Routing] Throw 405 instead of 404 when redirect is not possible
[Process] fix test case
Add security.tl.xlf to legacy directory
[Security][Validator] Add translations for Tagalog
fixed typo
Typo fix in security component lithuanian translation.
[Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder
* 2.7:
[Routing] Throw 405 instead of 404 when redirect is not possible
[Process] fix test case
Add security.tl.xlf to legacy directory
[Security][Validator] Add translations for Tagalog
fixed typo
Typo fix in security component lithuanian translation.
[Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder
This PR was squashed before being merged into the 4.1-dev branch (closes#22447).
Discussion
----------
[WebProfilerBundle] Imply forward request by a new X-Previous-Debug-Token header
| Q | A
| ------------- | ---
| Branch? | 4.1
| New feature? | yes
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | #... <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | symfony/symfony-docs#... <!--highly recommended for new features-->
TLDR; imply a "forwarded" request in the profiler if one _returns_ a response with a x-debug-token set. Otherwise dont.
____
Currently a forward request is implied by the WDT/profiler based on the latest sub-request made, however the main request can return it's own response, or one from a non-latest sub-request. The current behavior is a bit misleading imo.
```php
public function indexAction(Request $request)
{
$bar1 = $this->forward(__CLASS__.'::barAction');
$bar2 = $this->forward(__CLASS__.'::bar2Action');
return $bar1;
}
```
It shows the request was forwarded to `bar2Action`. This changes that, so that `barAction` is shown instead. No forward is implied if a new response was returned by `indexAction`.
![image](https://cloud.githubusercontent.com/assets/1047696/25064022/e24d999e-21f1-11e7-8f94-afa3fad7462f.png)
~~Note we dont really need the collector in the framework bundle anymore with this approach.~~ deprecated it.
Commits
-------
07dd09db59 [WebProfilerBundle] Imply forward request by a new X-Previous-Debug-Token header
This PR was merged into the 2.7 branch.
Discussion
----------
[Routing] Throw 405 instead of 404 when redirect is not possible
| Q | A
| ------------- | ---
| Branch? | 2.7
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Finishes #25962.
Commits
-------
92842814f6 [Routing] Throw 405 instead of 404 when redirect is not possible