# Technical Documentation: rectorphp/rector

> ℹ️ **Provenance:** Hybrid Fusion: `rectorphp/rector` (README + 10 In-Tree Chapters) · [CodeWiki Reference](https://codewiki.google/github.com/rectorphp/rector) · Recency: Active (< 180 days)

## 1. Project Overview & Quickstart (rectorphp/rector)

# Rector - Instant Upgrades and Automated Refactoring

[](https://packagist.org/packages/rector/rector)



Rector instantly upgrades and refactors the PHP code of your application.  It can help you in 2 major areas:

### 1. Instant Upgrades

Rector now supports upgrades from PHP 5.3 to 8.5 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), and [Doctrine](https://github.com/rectorphp/rector-doctrine). Do you want to **be constantly on the latest PHP and Framework without effort**?

Use Rector to handle **instant upgrades** for you.

### 2. Automated Refactoring

Do you have code quality you need, but struggle to keep it with new developers in your team? Do you want to see smart code-reviews even when every senior developers sleeps?

Add Rector to your CI and let it **continuously refactor your code** and keep the code quality high.

Read our [blogpost](https://getrector.com/blog/new-setup-ci-command-to-let-rector-work-for-you) to see how to set up automated refactoring.

## Install

```bash
composer require rector/rector --dev
```

## Running Rector

There are 2 main ways to use Rector:

- a *single rule*, to have the change under control
- or group of rules called *sets*

To use them, create a `rector.php` in your root directory:

```bash
vendor/bin/rector
```

And modify it:

```php
use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;

return RectorConfig::configure()
    // register single rule
    ->withRules([
        TypedPropertyFromStrictConstructorRector::class
    ])
    // here we can define, what prepared sets of rules will be applied
    ->withPreparedSets(
        deadCode: true,
        codeQuality: true
    );
```

Then dry run Rector:

```bash
vendor/bin/rector src --dry-run
```

Rector will show you diff of files that it *would* change. To *make* the changes, drop `--dry-run`:

```bash
vendor/bin/rector src
```

## Documentation

* Find [full documentation here](https://getrector.com/documentation/).
* [Explore Rector Rules](https://getrector.com/find-rule)



## Learn Faster with a Book

Are you curious, how Rector works internally, how to create your own rules and test them and why Rector was born?
Read [Rector - The Power of Automated Refactoring](https://leanpub.com/rector-the-power-of-automated-refactoring) that will take you step by step through the Rector setup and how to create your own rules.



## Empowered by Community :heart:

The Rector community is powerful thanks to active maintainers who take care of Rector sets for particular projects.

Among there projects belong:

* [palantirnet/drupal-rector](https://github.com/palantirnet/drupal-rector)
* [craftcms/rector](https://github.com/craftcms/rector)
* [FriendsOfShopware/shopware-rector](https://github.com/FriendsOfShopware/shopware-rector)
* [sabbelasichon/typo3-rector](https://github.com/sabbelasichon/typo3-rector)
* [sulu/sulu-rector](https://github.com/sulu/sulu-rector)
* [efabrica-team/rector-nette](https://github.com/efabrica-team/rector-nette)
* [Sylius/SyliusRector](https://github.com/Sylius/SyliusRector)
* [CoditoNet/rector-money](https://github.com/CoditoNet/rector-money)
* [laminas/laminas-servicemanager-migration](https://github.com/laminas/laminas-servicemanager-migration)
* [cakephp/upgrade](https://github.com/cakephp/upgrade)
* [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel)
* [contao/contao-rector](https://github.com/contao/contao-rector)
* [php-static-analysis/rector-rule](https://github.com/php-static-analysis/rector-rule)
* [ibexa/rector](https://github.com/ibexa/rector)
* [guanguans/rector-rules](https://github.com/guanguans/rector-rules)
* [wernerkrauss/silverstripe-rector](https://github.com/wernerkrauss/silverstripe-rector)



## Hire us to get Job Done :muscle:

Rector is a tool that [we develop](https://getrector.com/) and share for free, so anyone can automate their refactoring. But not everyone has dozens of hours to understand complexity of abstract-syntax-tree in their own time. **That's why we provide commercial support - to save your time**.

Would you like to apply Rector on your code base but don't have time for the struggle with your project? [Hire us](https://getrector.com/contact) to get there faster.



## How to Contribute

See [the contribution guide](/CONTRIBUTING.md) or go to development repository [rector/rector-src](https://github.com/rectorphp/rector-src).



## Debugging

You can use `--debug` option, that will print nested exceptions output:

```bash
vendor/bin/rector src/Controller --dry-run --debug
```

Or with Xdebug:

1. Make sure [Xdebug](https://xdebug.org/) is installed and configured
2. Add `--xdebug` option when running Rector

```bash
vendor/bin/rector src/Controller --dry-run --xdebug
```

To assist with simple debugging Rector provides 2 helpers to pretty-print AST-nodes:

```php
use PhpParser\Node\Scalar\String_;
$node = new String_('hello world!');

// prints node to string, as PHP code displays it
print_node($node);
```



## Known Drawbacks

* Rector uses [nikic/php-parser](https://github.com/nikic/PHP-Parser/), built on technology called an *abstract syntax tree* (AST). An AST doesn't know about spaces and when written to a file it produces poorly formatted code in both PHP and docblock annotations.

* Rector in parallel mode will work most of the times for most OS. On Windows, you may encounter issues unresolvable despite of following the [Troubleshooting Parallel](https://getrector.com/documentation/troubleshooting-parallel) guide. In such case, check if you are using Powershell 7 (pwsh). Change your terminal to command prompt (cmd) or bash for Windows.

### How to Apply Coding Standards?

**Your project needs to have a coding standard tool** and a set of formatting rules, so it can make Rector's output code nice and shiny again.

We're using [ECS](https://github.com/symplify/easy-coding-standard) with [this setup](https://github.com/rectorphp/rector-src/blob/main/ecs.php).

### May cause unexpected output on File with mixed PHP+HTML content

When you apply changes to files with PHP + HTML content, you may need to manually verify the changed file after apply the changes.

## 2. In-Tree Documentation Chapters (rectorphp/rector)

## File: README.md

# Rector - Instant Upgrades and Automated Refactoring

[](https://packagist.org/packages/rector/rector)



Rector instantly upgrades and refactors the PHP code of your application.  It can help you in 2 major areas:

### 1. Instant Upgrades

Rector now supports upgrades from PHP 5.3 to 8.5 and major open-source projects like [Symfony](https://github.com/rectorphp/rector-symfony), [PHPUnit](https://github.com/rectorphp/rector-phpunit), and [Doctrine](https://github.com/rectorphp/rector-doctrine). Do you want to **be constantly on the latest PHP and Framework without effort**?

Use Rector to handle **instant upgrades** for you.

### 2. Automated Refactoring

Do you have code quality you need, but struggle to keep it with new developers in your team? Do you want to see smart code-reviews even when every senior developers sleeps?

Add Rector to your CI and let it **continuously refactor your code** and keep the code quality high.

Read our [blogpost](https://getrector.com/blog/new-setup-ci-command-to-let-rector-work-for-you) to see how to set up automated refactoring.

## Install

```bash
composer require rector/rector --dev
```

## Running Rector

There are 2 main ways to use Rector:

- a *single rule*, to have the change under control
- or group of rules called *sets*

To use them, create a `rector.php` in your root directory:

```bash
vendor/bin/rector
```

And modify it:

```php
use Rector\Config\RectorConfig;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;

return RectorConfig::configure()
    // register single rule
    ->withRules([
        TypedPropertyFromStrictConstructorRector::class
    ])
    // here we can define, what prepared sets of rules will be applied
    ->withPreparedSets(
        deadCode: true,
        codeQuality: true
    );
```

Then dry run Rector:

```bash
vendor/bin/rector src --dry-run
```

Rector will show you diff of files that it *would* change. To *make* the changes, drop `--dry-run`:

```bash
vendor/bin/rector src
```

## Documentation

* Find [full documentation here](https://getrector.com/documentation/).
* [Explore Rector Rules](https://getrector.com/find-rule)



## Learn Faster with a Book

Are you curious, how Rector works internally, how to create your own rules and test them and why Rector was born?
Read [Rector - The Power of Automated Refactoring](https://leanpub.com/rector-the-power-of-automated-refactoring) that will take you step by step through the Rector setup and how to create your own rules.



## Empowered by Community :heart:

The Rector community is powerful thanks to active maintainers who take care of Rector sets for particular projects.

Among there projects belong:

* [palantirnet/drupal-rector](https://github.com/palantirnet/drupal-rector)
* [craftcms/rector](https://github.com/craftcms/rector)
* [FriendsOfShopware/shopware-rector](https://github.com/FriendsOfShopware/shopware-rector)
* [sabbelasichon/typo3-rector](https://github.com/sabbelasichon/typo3-rector)
* [sulu/sulu-rector](https://github.com/sulu/sulu-rector)
* [efabrica-team/rector-nette](https://github.com/efabrica-team/rector-nette)
* [Sylius/SyliusRector](https://github.com/Sylius/SyliusRector)
* [CoditoNet/rector-money](https://github.com/CoditoNet/rector-money)
* [laminas/laminas-servicemanager-migration](https://github.com/laminas/laminas-servicemanager-migration)
* [cakephp/upgrade](https://github.com/cakephp/upgrade)
* [driftingly/rector-laravel](https://github.com/driftingly/rector-laravel)
* [contao/contao-rector](https://github.com/contao/contao-rector)
* [php-static-analysis/rector-rule](https://github.com/php-static-analysis/rector-rule)
* [ibexa/rector](https://github.com/ibexa/rector)
* [guanguans/rector-rules](https://github.com/guanguans/rector-rules)
* [wernerkrauss/silverstripe-rector](https://github.com/wernerkrauss/silverstripe-rector)



## Hire us to get Job Done :muscle:

Rector is a tool that [we develop](https://getrector.com/) and share for free, so anyone can automate their refactoring. But not everyone has dozens of hours to understand complexity of abstract-syntax-tree in their own time. **That's why we provide commercial support - to save your time**.

Would you like to apply Rector on your code base but don't have time for the struggle with your project? [Hire us](https://getrector.com/contact) to get there faster.



## How to Contribute

See [the contribution guide](/CONTRIBUTING.md) or go to development repository [rector/rector-src](https://github.com/rectorphp/rector-src).



## Debugging

You can use `--debug` option, that will print nested exceptions output:

```bash
vendor/bin/rector src/Controller --dry-run --debug
```

Or with Xdebug:

1. Make sure [Xdebug](https://xdebug.org/) is installed and configured
2. Add `--xdebug` option when running Rector

```bash
vendor/bin/rector src/Controller --dry-run --xdebug
```

To assist with simple debugging Rector provides 2 helpers to pretty-print AST-nodes:

```php
use PhpParser\Node\Scalar\String_;
$node = new String_('hello world!');

// prints node to string, as PHP code displays it
print_node($node);
```



## Known Drawbacks

* Rector uses [nikic/php-parser](https://github.com/nikic/PHP-Parser/), built on technology called an *abstract syntax tree* (AST). An AST doesn't know about spaces and when written to a file it produces poorly formatted code in both PHP and docblock annotations.

* Rector in parallel mode will work most of the times for most OS. On Windows, you may encounter issues unresolvable despite of following the [Troubleshooting Parallel](https://getrector.com/documentation/troubleshooting-parallel) guide. In such case, check if you are using Powershell 7 (pwsh). Change your terminal to command prompt (cmd) or bash for Windows.

### How to Apply Coding Standards?

**Your project needs to have a coding standard tool** and a set of formatting rules, so it can make Rector's output code nice and shiny again.

We're using [ECS](https://github.com/symplify/easy-coding-standard) with [this setup](https://github.com/rectorphp/rector-src/blob/main/ecs.php).

### May cause unexpected output on File with mixed PHP+HTML content

When you apply changes to files with PHP + HTML content, you may need to manually verify the changed file after apply the changes.

---

## File: vendor/clue/ndjson-react/README.md

# clue/reactphp-ndjson

[](https://github.com/clue/reactphp-ndjson/actions)
[](https://packagist.org/packages/clue/ndjson-react)
[](#tests)

Streaming newline-delimited JSON ([NDJSON](http://ndjson.org/)) parser and encoder for [ReactPHP](https://reactphp.org/).

[NDJSON](http://ndjson.org/) can be used to store multiple JSON records in a
file to store any kind of (uniform) structured data, such as a list of user
objects or log entries. It uses a simple newline character between each
individual record and as such can be both used for efficient persistence and
simple append-style operations. This also allows it to be used in a streaming
context, such as a simple inter-process communication (IPC) protocol or for a
remote procedure call (RPC) mechanism. This library provides a simple
streaming API to process very large NDJSON files with thousands or even millions
of rows efficiently without having to load the whole file into memory at once.

* **Standard interfaces** -
  Allows easy integration with existing higher-level components by implementing
  ReactPHP's standard streaming interfaces.
* **Lightweight, SOLID design** -
  Provides a thin abstraction that is [*just good enough*](https://en.wikipedia.org/wiki/Principle_of_good_enough)
  and does not get in your way.
  Builds on top of well-tested components and well-established concepts instead of reinventing the wheel.
* **Good test coverage** -
  Comes with an [automated tests suite](#tests) and is regularly tested in the *real world*.

**Table of contents**

* [Support us](#support-us)
* [NDJSON format](#ndjson-format)
* [Usage](#usage)
    * [Decoder](#decoder)
    * [Encoder](#encoder)
* [Install](#install)
* [Tests](#tests)
* [License](#license)
* [More](#more)

## Support us

We invest a lot of time developing, maintaining, and updating our awesome
open-source projects. You can help us sustain this high-quality of our work by
[becoming a sponsor on GitHub](https://github.com/sponsors/clue). Sponsors get
numerous benefits in return, see our [sponsoring page](https://github.com/sponsors/clue)
for details.

Let's take these projects to the next level together! 🚀

## NDJSON format

NDJSON ("Newline-Delimited JSON" or sometimes referred to as "JSON lines") is a
very simple text-based format for storing a large number of records, such as a
list of user records or log entries.

```JSON
{"name":"Alice","age":30,"comment":"Yes, I like cheese"}
{"name":"Bob","age":50,"comment":"Hello\nWorld!"}
```

If you understand JSON and you're now looking at this newline-delimited JSON for
the first time, you should already know everything you need to know to
understand NDJSON: As the name implies, this format essentially consists of
individual lines where each individual line is any valid JSON text and each line
is delimited with a newline character.

This example uses a list of user objects where each user has some arbitrary
properties. This can easily be adjusted for many different use cases, such as
storing for example products instead of users, assigning additional properties
or having a significantly larger number of records. You can edit NDJSON files in
any text editor or use them in a streaming context where individual records
should be processed. Unlike normal JSON files, adding a new log entry to this
NDJSON file does not require modification of this file's structure (note there's
no "outer array" to be modified). This makes it a perfect fit for a streaming
context, for line-oriented CLI tools (such as `grep` and others) or for a logging
context where you want to append records at a later time. Additionally, this
also allows it to be used in a streaming context, such as a simple inter-process
communication (IPC) protocol or for a remote procedure call (RPC) mechanism.

The newline character at the end of each line allows for some really simple
*framing* (detecting individual records). While each individual line is valid
JSON, the complete file as a whole is technically no longer valid JSON, because
it contains multiple JSON texts. This implies that for example calling PHP's
`json_decode()` on this complete input would fail because it would try to parse
multiple records at once. Likewise, using "pretty printing" JSON
(`JSON_PRETTY_PRINT`) is not allowed because each JSON text is limited to exactly
one line. On the other hand, values containing newline characters (such as the
`comment` property in the above example) do not cause issues because each newline
within a JSON string will be represented by a `\n` instead.

One common alternative to NDJSON would be Comma-Separated Values (CSV).
If you want to process CSV files, you may want to take a look at the related
project [clue/reactphp-csv](https://github.com/clue/reactphp-csv) instead:

```
name,age,comment
Alice,30,"Yes, I like cheese"
Bob,50,"Hello
World!"
```

CSV may look slightly simpler, but this simplicity comes at a price. CSV is
limited to untyped, two-dimensional data, so there's no standard way of storing
any nested structures or to differentiate a boolean value from a string or
integer. Field names are sometimes used, sometimes they're not
(application-dependant). Inconsistent handling for fields that contain
separators such as `,` or spaces or line breaks (see the `comment` field above)
introduce additional complexity and its text encoding is usually undefined,
Unicode (or UTF-8) is unlikely to be supported and CSV files often use ISO
8859-1 encoding or some variant (again application-dependant).

While NDJSON helps avoiding many of CSV's shortcomings, it is still a
(relatively) young format while CSV files have been used in production systems
for decades. This means that if you want to interface with an existing system,
you may have to rely on the format that's already supported. If you're building
a new system, using NDJSON is an excellent choice as it provides a flexible way
to process individual records using a common text-based format that can include
any kind of structured data.

## Usage

### Decoder

The `Decoder` (parser) class can be used to make sure you only get back
complete, valid JSON elements when reading from a stream.
It wraps a given
[`ReadableStreamInterface`](https://github.com/reactphp/stream#readablestreaminterface)
and exposes its data through the same interface, but emits the JSON elements
as parsed values instead of just chunks of strings:

```
{"name":"test","active":true}
{"name":"hello w\u00f6rld","active":true}
```

```php
$stdin = new React\Stream\ReadableResourceStream(STDIN);

$ndjson = new Clue\React\NDJson\Decoder($stdin);

$ndjson->on('data', function ($data) {
    // $data is a parsed element from the JSON stream
    // line 1: $data = (object)array('name' => 'test', 'active' => true);
    // line 2: $data = (object)array('name' => 'hello wörld', 'active' => true);
    var_dump($data);
});
```

ReactPHP's streams emit chunks of data strings and make no assumption about their lengths.
These chunks do not necessarily represent complete JSON elements, as an
element may be broken up into multiple chunks.
This class reassembles these elements by buffering incomplete ones.

The `Decoder` supports the same optional parameters as the underlying
[`json_decode()`](https://www.php.net/manual/en/function.json-decode.php) function.
This means that, by default, JSON objects will be emitted as a `stdClass`.
This behavior can be controlled through the optional constructor parameters:

```php
$ndjson = new Clue\React\NDJson\Decoder($stdin, true);

$ndjson->on('data', function ($data) {
    // JSON objects will be emitted as assoc arrays now
});
```

Additionally, the `Decoder` limits the maximum buffer size (maximum line
length) to avoid buffer overflows due to malformed user input. Usually, there
should be no need to change this value, unless you know you're dealing with some
unreasonably long lines. It accepts an additional argument if you want to change
this from the default of 64 KiB:

```php
$ndjson = new Clue\React\NDJson\Decoder($stdin, false, 512, 0, 64 * 1024);
```

If the underlying stream emits an `error` event or the plain stream contains
any data that does not represent a valid NDJson stream,
it will emit an `error` event and then `close` the input stream:

```php
$ndjson->on('error', function (Exception $error) {
    // an error occured, stream will close next
});
```

If the underlying stream emits an `end` event, it will flush any incomplete
data from the buffer, thus either possibly emitting a final `data` event
followed by an `end` event on success or an `error` event for
incomplete/invalid JSON data as above:

```php
$ndjson->on('end', function () {
    // stream successfully ended, stream will close next
});
```

If either the underlying stream or the `Decoder` is closed, it will forward
the `close` event:

```php
$ndjson->on('close', function () {
    // stream closed
    // possibly after an "end" event or due to an "error" event
});
```

The `close(): void` method can be used to explicitly close the `Decoder` and
its underlying stream:

```php
$ndjson->close();
```

The `pipe(WritableStreamInterface $dest, array $options = array(): WritableStreamInterface`
method can be used to forward all data to the given destination stream.
Please note that the `Decoder` emits decoded/parsed data events, while many
(most?) writable streams expect only data chunks:

```php
$ndjson->pipe($logger);
```

For more details, see ReactPHP's
[`ReadableStreamInterface`](https://github.com/reactphp/stream#readablestreaminterface).

### Encoder

The `Encoder` (serializer) class can be used to make sure anything you write to
a stream ends up as valid JSON elements in the resulting NDJSON stream.
It wraps a given
[`WritableStreamInterface`](https://github.com/reactphp/stream#writablestreaminterface)
and accepts its data through the same interface, but handles any data as complete
JSON elements instead of just chunks of strings:

```php
$stdout = new React\Stream\WritableResourceStream(STDOUT);

$ndjson = new Clue\React\NDJson\Encoder($stdout);

$ndjson->write(array('name' => 'test', 'active' => true));
$ndjson->write(array('name' => 'hello wörld', 'active' => true));
```
```
{"name":"test","active":true}
{"name":"hello w\u00f6rld","active":true}
```

The `Encoder` supports the same parameters as the underlying
[`json_encode()`](https://www.php.net/manual/en/function.json-encode.php) function.
This means that, by default, Unicode characters will be escaped in the output.
This behavior can be controlled through the optional constructor parameters:

```php
$ndjson = new Clue\React\NDJson\Encoder($stdout, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

$ndjson->write('hello wörld');
```
```
"hello wörld"
```

Note that trying to pass the `JSON_PRETTY_PRINT` option will yield an
`InvalidArgumentException` because it is not compatible with NDJSON.

If the underlying stream emits an `error` event or the given data contains
any data that can not be represented as a valid NDJSON stream,
it will emit an `error` event and then `close` the input stream:

```php
$ndjson->on('error', function (Exception $error) {
    // an error occured, stream will close next
});
```

If either the underlying stream or the `Encoder` is closed, it will forward
the `close` event:

```php
$ndjson->on('close', function () {
    // stream closed
    // possibly after an "end" event or due to an "error" event
});
```

The `end(mixed $data = null): void` method can be used to optionally emit
any final data and then soft-close the `Encoder` and its underlying stream:

```php
$ndjson->end();
```

The `close(): void` method can be used to explicitly close the `Encoder` and
its underlying stream:

```php
$ndjson->close();
```

For more details, see ReactPHP's
[`WritableStreamInterface`](https://github.com/reactphp/stream#writablestreaminterface).

## Install

The recommended way to install this library is [through Composer](https://getcomposer.org/).
[New to Composer?](https://getcomposer.org/doc/00-intro.md)

This project follows [SemVer](https://semver.org/).
This will install the latest supported version:

```bash
composer require clue/ndjson-react:^1.3
```

See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.

This project aims to run on any platform and thus does not require any PHP
extensions and supports running on legacy PHP 5.3 through current PHP 8+ and
HHVM.
It's *highly recommended to use the latest supported PHP version* for this project.

## Tests

To run the test suite, you first need to clone this repo and then install all
dependencies [through Composer](https://getcomposer.org/):

```bash
composer install
```

To run the test suite, go to the project root and run:

```bash
vendor/bin/phpunit
```

## License

This project is released under the permissive [MIT license](LICENSE).

> Did you know that I offer custom development services and issuing invoices for
  sponsorships of releases and for contributions? Contact me (@clue) for details.

## More

* If you want to learn more about processing streams of data, refer to the documentation of
  the underlying [react/stream](https://github.com/reactphp/stream) component.

* If you want to process compressed NDJSON files (`.ndjson.gz` file extension),
  you may want to use [clue/reactphp-zlib](https://github.com/clue/reactphp-zlib)
  on the compressed input stream before passing the decompressed stream to the NDJSON decoder.

* If you want to create compressed NDJSON files (`.ndjson.gz` file extension),
  you may want to use [clue/reactphp-zlib](https://github.com/clue/reactphp-zlib)
  on the resulting NDJSON encoder output stream before passing the compressed
  stream to the file output stream.

* If you want to concurrently process the records from your NDJSON stream,
  you may want to use [clue/reactphp-flux](https://github.com/clue/reactphp-flux)
  to concurrently process many (but not too many) records at once.

* If you want to process structured data in the more common text-based format,
  you may want to use [clue/reactphp-csv](https://github.com/clue/reactphp-csv)
  to process Comma-Separated-Values (CSV) files (`.csv` file extension).

---

## File: vendor/composer/pcre/README.md

composer/pcre
=============

PCRE wrapping library that offers type-safe `preg_*` replacements.

This library gives you a way to ensure `preg_*` functions do not fail silently, returning
unexpected `null`s that may not be handled.

As of 3.0 this library enforces [`PREG_UNMATCHED_AS_NULL`](#preg_unmatched_as_null) usage
for all matching and replaceCallback functions, [read more below](#preg_unmatched_as_null)
to understand the implications.

It thus makes it easier to work with static analysis tools like PHPStan or Psalm as it
simplifies and reduces the possible return values from all the `preg_*` functions which
are quite packed with edge cases. As of v2.2.0 / v3.2.0 the library also comes with a
[PHPStan extension](#phpstan-extension) for parsing regular expressions and giving you even better output types.

This library is a thin wrapper around `preg_*` functions with [some limitations](#restrictions--limitations).
If you are looking for a richer API to handle regular expressions have a look at
[rawr/t-regx](https://packagist.org/packages/rawr/t-regx) instead.

[](https://github.com/composer/pcre/actions)


Installation
------------

Install the latest version with:

```bash
$ composer require composer/pcre
```


Requirements
------------

* PHP 7.4.0 is required for 3.x versions
* PHP 7.2.0 is required for 2.x versions
* PHP 5.3.2 is required for 1.x versions


Basic usage
-----------

Instead of:

```php
if (preg_match('{fo+}', $string, $matches)) { ... }
if (preg_match('{fo+}', $string, $matches, PREG_OFFSET_CAPTURE)) { ... }
if (preg_match_all('{fo+}', $string, $matches)) { ... }
$newString = preg_replace('{fo+}', 'bar', $string);
$newString = preg_replace_callback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
$newString = preg_replace_callback_array(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
$filtered = preg_grep('{[a-z]}', $elements);
$array = preg_split('{[a-z]+}', $string);
```

You can now call these on the `Preg` class:

```php
use Composer\Pcre\Preg;

if (Preg::match('{fo+}', $string, $matches)) { ... }
if (Preg::matchWithOffsets('{fo+}', $string, $matches)) { ... }
if (Preg::matchAll('{fo+}', $string, $matches)) { ... }
$newString = Preg::replace('{fo+}', 'bar', $string);
$newString = Preg::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
$newString = Preg::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
$filtered = Preg::grep('{[a-z]}', $elements);
$array = Preg::split('{[a-z]+}', $string);
```

The main difference is if anything fails to match/replace/.., it will throw a `Composer\Pcre\PcreException`
instead of returning `null` (or false in some cases), so you can now use the return values safely relying on
the fact that they can only be strings (for replace), ints (for match) or arrays (for grep/split).

Additionally the `Preg` class provides match methods that return `bool` rather than `int`, for stricter type safety
when the number of pattern matches is not useful:

```php
use Composer\Pcre\Preg;

if (Preg::isMatch('{fo+}', $string, $matches)) // bool
if (Preg::isMatchAll('{fo+}', $string, $matches)) // bool
```

Finally the `Preg` class provides a few `*StrictGroups` method variants that ensure match groups
are always present and thus non-nullable, making it easier to write type-safe code:

```php
use Composer\Pcre\Preg;

// $matches is guaranteed to be an array of strings, if a subpattern does not match and produces a null it will throw
if (Preg::matchStrictGroups('{fo+}', $string, $matches))
if (Preg::matchAllStrictGroups('{fo+}', $string, $matches))
```

**Note:** This is generally safe to use as long as you do not have optional subpatterns (i.e. `(something)?`
or `(something)*` or branches with a `|` that result in some groups not being matched at all).
A subpattern that can match an empty string like `(.*)` is **not** optional, it will be present as an
empty string in the matches. A non-matching subpattern, even if optional like `(?:foo)?` will anyway not be present in
matches so it is also not a problem to use these with `*StrictGroups` methods.

If you would prefer a slightly more verbose usage, replacing by-ref arguments by result objects, you can use the `Regex` class:

```php
use Composer\Pcre\Regex;

// this is useful when you are just interested in knowing if something matched
// as it returns a bool instead of int(1/0) for match
$bool = Regex::isMatch('{fo+}', $string);

$result = Regex::match('{fo+}', $string);
if ($result->matched) { something($result->matches); }

$result = Regex::matchWithOffsets('{fo+}', $string);
if ($result->matched) { something($result->matches); }

$result = Regex::matchAll('{fo+}', $string);
if ($result->matched && $result->count > 3) { something($result->matches); }

$newString = Regex::replace('{fo+}', 'bar', $string)->result;
$newString = Regex::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string)->result;
$newString = Regex::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string)->result;
```

Note that `preg_grep` and `preg_split` are only callable via the `Preg` class as they do not have
complex return types warranting a specific result object.

See the [MatchResult](src/MatchResult.php), [MatchWithOffsetsResult](src/MatchWithOffsetsResult.php), [MatchAllResult](src/MatchAllResult.php),
[MatchAllWithOffsetsResult](src/MatchAllWithOffsetsResult.php), and [ReplaceResult](src/ReplaceResult.php) class sources for more details.

Restrictions / Limitations
--------------------------

Due to type safety requirements a few restrictions are in place.

- matching using `PREG_OFFSET_CAPTURE` is made available via `matchWithOffsets` and `matchAllWithOffsets`.
  You cannot pass the flag to `match`/`matchAll`.
- `Preg::split` will also reject `PREG_SPLIT_OFFSET_CAPTURE` and you should use `splitWithOffsets`
  instead.
- `matchAll` rejects `PREG_SET_ORDER` as it also changes the shape of the returned matches. There
  is no alternative provided as you can fairly easily code around it.
- `preg_filter` is not supported as it has a rather crazy API, most likely you should rather
  use `Preg::grep` in combination with some loop and `Preg::replace`.
- `replace`, `replaceCallback` and `replaceCallbackArray` do not support an array `$subject`,
  only simple strings.
- As of 2.0, the library always uses `PREG_UNMATCHED_AS_NULL` for matching, which offers [much
  saner/more predictable results](#preg_unmatched_as_null). As of 3.0 the flag is also set for
  `replaceCallback` and `replaceCallbackArray`.

#### PREG_UNMATCHED_AS_NULL

As of 2.0, this library always uses PREG_UNMATCHED_AS_NULL for all `match*` and `isMatch*`
functions. As of 3.0 it is also done for `replaceCallback` and `replaceCallbackArray`.

This means your matches will always contain all matching groups, either as null if unmatched
or as string if it matched.

The advantages in clarity and predictability are clearer if you compare the two outputs of
running this with and without PREG_UNMATCHED_AS_NULL in $flags:

```php
preg_match('/(a)(b)*(c)(d)*/', 'ac', $matches, $flags);
```

| no flag | PREG_UNMATCHED_AS_NULL |
| --- | --- |
| array (size=4)              | array (size=5) |
| 0 => string 'ac' (length=2) |   0 => string 'ac' (length=2) |
| 1 => string 'a' (length=1)  |   1 => string 'a' (length=1) |
| 2 => string '' (length=0)   |   2 => null |
| 3 => string 'c' (length=1)  |   3 => string 'c' (length=1) |
|                             |   4 => null |
| group 2 (any unmatched group preceding one that matched) is set to `''`. You cannot tell if it matched an empty string or did not match at all | group 2 is `null` when unmatched and a string if it matched, easy to check for |
| group 4 (any optional group without a matching one following) is missing altogether. So you have to check with `isset()`, but really you want `isset($m[4]) && $m[4] !== ''` for safety unless you are very careful to check that a non-optional group follows it | group 4 is always set, and null in this case as there was no match, easy to check for with `$m[4] !== null` |

PHPStan Extension
-----------------

To use the PHPStan extension if you do not use `phpstan/extension-installer` you can include `vendor/composer/pcre/extension.neon` in your PHPStan config.

The extension provides much better type information for $matches as well as regex validation where possible.

License
-------

composer/pcre is licensed under the MIT License, see the LICENSE file for details.

---

## File: vendor/composer/semver/README.md

composer/semver
===============

Semver (Semantic Versioning) library that offers utilities, version constraint parsing and validation.

Originally written as part of [composer/composer](https://github.com/composer/composer),
now extracted and made available as a stand-alone library.

[](https://github.com/composer/semver/actions/workflows/continuous-integration.yml)
[](https://github.com/composer/semver/actions/workflows/lint.yml)
[](https://github.com/composer/semver/actions/workflows/phpstan.yml)

Installation
------------

Install the latest version with:

```bash
composer require composer/semver
```


Requirements
------------

* PHP 5.3.2 is required but using the latest version of PHP is highly recommended.


Version Comparison
------------------

For details on how versions are compared, refer to the [Versions](https://getcomposer.org/doc/articles/versions.md)
article in the documentation section of the [getcomposer.org](https://getcomposer.org) website.


Basic usage
-----------

### Comparator

The [`Composer\Semver\Comparator`](https://github.com/composer/semver/blob/main/src/Comparator.php) class provides the following methods for comparing versions:

* greaterThan($v1, $v2)
* greaterThanOrEqualTo($v1, $v2)
* lessThan($v1, $v2)
* lessThanOrEqualTo($v1, $v2)
* equalTo($v1, $v2)
* notEqualTo($v1, $v2)

Each function takes two version strings as arguments and returns a boolean. For example:

```php
use Composer\Semver\Comparator;

Comparator::greaterThan('1.25.0', '1.24.0'); // 1.25.0 > 1.24.0
```

### Semver

The [`Composer\Semver\Semver`](https://github.com/composer/semver/blob/main/src/Semver.php) class provides the following methods:

* satisfies($version, $constraints)
* satisfiedBy(array $versions, $constraint)
* sort($versions)
* rsort($versions)

### Intervals

The [`Composer\Semver\Intervals`](https://github.com/composer/semver/blob/main/src/Intervals.php) static class provides
a few utilities to work with complex constraints or read version intervals from a constraint:

```php
use Composer\Semver\Intervals;

// Checks whether $candidate is a subset of $constraint
Intervals::isSubsetOf(ConstraintInterface $candidate, ConstraintInterface $constraint);

// Checks whether $a and $b have any intersection, equivalent to $a->matches($b)
Intervals::haveIntersections(ConstraintInterface $a, ConstraintInterface $b);

// Optimizes a complex multi constraint by merging all intervals down to the smallest
// possible multi constraint. The drawbacks are this is not very fast, and the resulting
// multi constraint will have no human readable prettyConstraint configured on it
Intervals::compactConstraint(ConstraintInterface $constraint);

// Creates an array of numeric intervals and branch constraints representing a given constraint
Intervals::get(ConstraintInterface $constraint);

// Clears the memoization cache when you are done processing constraints
Intervals::clear()
```

See the class docblocks for more details.


License
-------

composer/semver is licensed under the MIT License, see the LICENSE file for details.

---

## File: vendor/composer/xdebug-handler/README.md

# composer/xdebug-handler

[](https://packagist.org/packages/composer/xdebug-handler)
[](https://github.com/composer/xdebug-handler/actions?query=branch:main)



Restart a CLI process without loading the Xdebug extension, unless `xdebug.mode=off`.

Originally written as part of [composer/composer](https://github.com/composer/composer),
now extracted and made available as a stand-alone library.

### Version 3

Removed support for legacy PHP versions and added type declarations.

Long term support for version 2 (PHP 5.3.2 - 7.2.4) follows [Composer 2.2 LTS](https://blog.packagist.com/composer-2-2/) policy.

## Installation

Install the latest version with:

```bash
$ composer require composer/xdebug-handler
```

## Requirements

* PHP 7.2.5 minimum, although using the latest PHP version is highly recommended.

## Basic Usage
```php
use Composer\XdebugHandler\XdebugHandler;

$xdebug = new XdebugHandler('myapp');
$xdebug->check();
unset($xdebug);
```

The constructor takes a single parameter, `$envPrefix`, which is upper-cased and prepended to default base values to create two distinct environment variables. The above example enables the use of:

- `MYAPP_ALLOW_XDEBUG=1` to override automatic restart and allow Xdebug
- `MYAPP_ORIGINAL_INIS` to obtain ini file locations in a restarted process

## Advanced Usage

* [How it works](#how-it-works)
* [Limitations](#limitations)
* [Helper methods](#helper-methods)
* [Setter methods](#setter-methods)
* [Process configuration](#process-configuration)
* [Troubleshooting](#troubleshooting)
* [Extending the library](#extending-the-library)
* [Examples](#examples)

### How it works

A temporary ini file is created from the loaded (and scanned) ini files, with any references to the Xdebug extension commented out. Current ini settings are merged, so that most ini settings made on the command-line or by the application are included (see [Limitations](#limitations))

* `MYAPP_ALLOW_XDEBUG` is set with internal data to flag and use in the restart.
* The command-line and environment are [configured](#process-configuration) for the restart.
* The application is restarted in a new process.
    * The restart settings are stored in the environment.
    * `MYAPP_ALLOW_XDEBUG` is unset.
    * The application runs and exits.
* The main process exits with the exit code from the restarted process.

See [Examples](#examples) for further information.

#### Signal handling
Asynchronous signal handling is automatically enabled if the pcntl extension is loaded. `SIGINT` is set to `SIG_IGN` in the parent
process and restored to `SIG_DFL` in the restarted process (if no other handler has been set).

From PHP 7.4 on Windows, `CTRL+C` and `CTRL+BREAK` handling is automatically enabled in the restarted process and ignored in the parent process.

### Limitations
There are a few things to be aware of when running inside a restarted process.

* Extensions set on the command-line will not be loaded.
* Ini file locations will be reported as per the restart - see [getAllIniFiles()](#getallinifiles-array).
* Php sub-processes may be loaded with Xdebug enabled - see [Process configuration](#process-configuration).

### Helper methods
These static methods provide information from the current process, regardless of whether it has been restarted or not.

#### _getAllIniFiles(): array_
Returns an array of the original ini file locations. Use this instead of calling `php_ini_loaded_file` and `php_ini_scanned_files`, which will report the wrong values in a restarted process.

```php
use Composer\XdebugHandler\XdebugHandler;

$files = XdebugHandler::getAllIniFiles();

# $files[0] always exists, it could be an empty string
$loadedIni = array_shift($files);
$scannedInis = $files;
```

These locations are also available in the `MYAPP_ORIGINAL_INIS` environment variable. This is a path-separated string comprising the location returned from `php_ini_loaded_file`, which could be empty, followed by locations parsed from calling `php_ini_scanned_files`.

#### _getRestartSettings(): ?array_
Returns an array of settings that can be used with PHP [sub-processes](#sub-processes), or null if the process was not restarted.

```php
use Composer\XdebugHandler\XdebugHandler;

$settings = XdebugHandler::getRestartSettings();
/**
 * $settings: array (if the current process was restarted,
 * or called with the settings from a previous restart), or null
 *
 *    'tmpIni'      => the temporary ini file used in the restart (string)
 *    'scannedInis' => if there were any scanned inis (bool)
 *    'scanDir'     => the original PHP_INI_SCAN_DIR value (false|string)
 *    'phprc'       => the original PHPRC value (false|string)
 *    'inis'        => the original inis from getAllIniFiles (array)
 *    'skipped'     => the skipped version from getSkippedVersion (string)
 */
```

#### _getSkippedVersion(): string_
Returns the Xdebug version string that was skipped by the restart, or an empty string if there was no restart (or Xdebug is still loaded, perhaps by an extending class restarting for a reason other than removing Xdebug).

```php
use Composer\XdebugHandler\XdebugHandler;

$version = XdebugHandler::getSkippedVersion();
# $version: '3.1.1' (for example), or an empty string
```

#### _isXdebugActive(): bool_
Returns true if Xdebug is loaded and is running in an active mode (if it supports modes). Returns false if Xdebug is not loaded, or it is running with `xdebug.mode=off`.

### Setter methods
These methods implement a fluent interface and must be called before the main `check()` method.

#### _setLogger(LoggerInterface $logger): self_
Enables the output of status messages to an external PSR3 logger. All messages are reported with either `DEBUG` or `WARNING` log levels. For example (showing the level and message):

```
// No restart
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.1) xdebug.mode=off
DEBUG    No restart (APP_ALLOW_XDEBUG=0) Allowed by xdebug.mode

// Restart overridden
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.1) xdebug.mode=coverage,debug,develop
DEBUG    No restart (MYAPP_ALLOW_XDEBUG=1)

// Failed restart
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.0)
WARNING  No restart (Unable to create temp ini file at: ...)
```

Status messages can also be output with `XDEBUG_HANDLER_DEBUG`. See [Troubleshooting](#troubleshooting).

#### _setMainScript(string $script): self_
Sets the location of the main script to run in the restart. This is only needed in more esoteric use-cases, or if the `argv[0]` location is inaccessible. The script name `--` is supported for standard input.

#### _setPersistent(): self_
Configures the restart using [persistent settings](#persistent-settings), so that Xdebug is not loaded in any sub-process.

Use this method if your application invokes one or more PHP sub-process and the Xdebug extension is not needed. This avoids the overhead of implementing specific [sub-process](#sub-processes) strategies.

Alternatively, this method can be used to set up a default _Xdebug-free_ environment which can be changed if a sub-process requires Xdebug, then restored afterwards:

```php
function SubProcessWithXdebug()
{
    $phpConfig = new Composer\XdebugHandler\PhpConfig();

    # Set the environment to the original configuration
    $phpConfig->useOriginal();

    # run the process with Xdebug loaded
    ...

    # Restore Xdebug-free environment
    $phpConfig->usePersistent();
}
```

### Process configuration
The library offers two strategies to invoke a new PHP process without loading Xdebug, using either _standard_ or _persistent_ settings. Note that this is only important if the application calls a PHP sub-process.

#### Standard settings
Uses command-line options to remove Xdebug from the new process only.

* The -n option is added to the command-line. This tells PHP not to scan for additional inis.
* The temporary ini is added to the command-line with the -c option.

>_If the new process calls a PHP sub-process, Xdebug will be loaded in that sub-process (unless it implements xdebug-handler, in which case there will be another restart)._

This is the default strategy used in the restart.

#### Persistent settings
Uses environment variables to remove Xdebug from the new process and persist these settings to any sub-process.

* `PHP_INI_SCAN_DIR` is set to an empty string. This tells PHP not to scan for additional inis.
* `PHPRC` is set to the temporary ini.

>_If the new process calls a PHP sub-process, Xdebug will not be loaded in that sub-process._

This strategy can be used in the restart by calling [setPersistent()](#setpersistent-self).

#### Sub-processes
The `PhpConfig` helper class makes it easy to invoke a PHP sub-process (with or without Xdebug loaded), regardless of whether there has been a restart.

Each of its methods returns an array of PHP options (to add to the command-line) and sets up the environment for the required strategy. The [getRestartSettings()](#getrestartsettings-array) method is used internally.

* `useOriginal()` - Xdebug will be loaded in the new process.
* `useStandard()` - Xdebug will **not** be loaded in the new process - see [standard settings](#standard-settings).
* `userPersistent()` - Xdebug will **not** be loaded in the new process - see [persistent settings](#persistent-settings)

If there was no restart, an empty options array is returned and the environment is not changed.

```php
use Composer\XdebugHandler\PhpConfig;

$config = new PhpConfig;

$options = $config->useOriginal();
# $options:     empty array
# environment:  PHPRC and PHP_INI_SCAN_DIR set to original values

$options = $config->useStandard();
# $options:     [-n, -c, tmpIni]
# environment:  PHPRC and PHP_INI_SCAN_DIR set to original values

$options = $config->usePersistent();
# $options:     empty array
# environment:  PHPRC=tmpIni, PHP_INI_SCAN_DIR=''
```

### Troubleshooting
The following environment settings can be used to troubleshoot unexpected behavior:

* `XDEBUG_HANDLER_DEBUG=1` Outputs status messages to `STDERR`, if it is defined, irrespective of any PSR3 logger. Each message is prefixed `xdebug-handler[pid]`, where pid is the process identifier.

* `XDEBUG_HANDLER_DEBUG=2` As above, but additionally saves the temporary ini file and reports its location in a status message.

### Extending the library
The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality:

#### _requiresRestart(bool $default): bool_
By default the process will restart if Xdebug is loaded and not running with `xdebug.mode=off`. Extending this method allows an application to decide, by returning a boolean (or equivalent) value.
It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden.

Note that the [setMainScript()](#setmainscriptstring-script-self) and [setPersistent()](#setpersistent-self) setters can be used here, if required.

#### _restart(array $command): void_
An application can extend this to modify the temporary ini file, its location given in the `tmpIni` property. New settings can be safely appended to the end of the data, which is `PHP_EOL` terminated.

The `$command` parameter is an array of unescaped command-line arguments that will be used for the new process.

Remember to finish with `parent::restart($command)`.

#### Example
This example demonstrates two ways to extend basic functionality:

* To avoid the overhead of spinning up a new process, the restart is skipped if a simple help command is requested.

* The application needs write-access to phar files, so it will force a restart if `phar.readonly` is set (regardless of whether Xdebug is loaded) and change this value in the temporary ini file.

```php
use Composer\XdebugHandler\XdebugHandler;
use MyApp\Command;

class MyRestarter extends XdebugHandler
{
    private $required;

    protected function requiresRestart(bool $default): bool
    {
        if (Command::isHelp()) {
            # No need to disable Xdebug for this
            return false;
        }

        $this->required = (bool) ini_get('phar.readonly');
        return $this->required || $default;
    }

    protected function restart(array $command): void
    {
        if ($this->required) {
            # Add required ini setting to tmpIni
            $content = file_get_contents($this->tmpIni);
            $content .= 'phar.readonly=0'.PHP_EOL;
            file_put_contents($this->tmpIni, $content);
        }

        parent::restart($command);
    }
}
```

### Examples
The `tests\App` directory contains command-line scripts that demonstrate the internal workings in a variety of scenarios.
See [Functional Test Scripts](./tests/App/README.md).

## License
composer/xdebug-handler is licensed under the MIT License, see the LICENSE file for details.

---

## File: vendor/doctrine/inflector/README.md

# Doctrine Inflector

Doctrine Inflector is a small library that can perform string manipulations
with regard to uppercase/lowercase and singular/plural forms of words.

[](https://github.com/doctrine/inflector/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x)
[](https://codecov.io/gh/doctrine/inflector/branch/2.0.x)

---

## File: vendor/evenement/evenement/README.md

# Événement

Événement is a very simple event dispatching library for PHP.

It has the same design goals as [Silex](https://silex.symfony.com/) and
[Pimple](https://github.com/silexphp/Pimple), to empower the user while staying concise
and simple.

It is very strongly inspired by the [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) API found in
[node.js](http://nodejs.org).


[](https://packagist.org/packages/evenement/evenement)
[](https://packagist.org/packages/evenement/evenement/stats)
[](https://packagist.org/packages/evenement/evenement)

## Fetch

The recommended way to install Événement is [through composer](http://getcomposer.org). By running the following command:

    $ composer require evenement/evenement

## Usage

### Creating an Emitter

```php
<?php
$emitter = new Evenement\EventEmitter();
```

### Adding Listeners

```php
<?php
$emitter->on('user.created', function (User $user) use ($logger) {
    $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
});
```

### Removing Listeners

```php
<?php
$emitter->removeListener('user.created', function (User $user) use ($logger) {
    $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
});
```

### Emitting Events

```php
<?php
$emitter->emit('user.created', [$user]);
```

Tests
-----

    $ ./vendor/bin/phpunit

License
-------
MIT, see LICENSE.

---

## File: vendor/fidry/cpu-core-counter/README.md

# CPU Core Counter

This package is a tiny utility to get the number of CPU cores.

```sh
composer require fidry/cpu-core-counter
```


## Usage

```php
use Fidry\CpuCoreCounter\CpuCoreCounter;
use Fidry\CpuCoreCounter\NumberOfCpuCoreNotFound;
use Fidry\CpuCoreCounter\Finder\DummyCpuCoreFinder;

$counter = new CpuCoreCounter();

// For knowing the number of cores you can use for launching parallel processes:
$counter->getAvailableForParallelisation()->availableCpus;

// Get the number of CPU cores (by default it will use the logical cores count):
try {
    $counter->getCount();   // e.g. 8
} catch (NumberOfCpuCoreNotFound) {
    return 1;   // Fallback value
}

// An alternative form where we not want to catch the exception:

$counter = new CpuCoreCounter([
    ...CpuCoreCounter::getDefaultFinders(),
    new DummyCpuCoreFinder(1),  // Fallback value
]);

// A type-safe alternative form:
$counter->getCountWithFallback(1);

// Note that the result is memoized.
$counter->getCount();   // e.g. 8

```


## Advanced usage

### Changing the finders

When creating `CpuCoreCounter`, you may want to change the order of the finders
used or disable a specific finder. You can easily do so by passing the finders
you want

```php
// Remove WindowsWmicFinder 
$finders = array_filter(
    CpuCoreCounter::getDefaultFinders(),
    static fn (CpuCoreFinder $finder) => !($finder instanceof WindowsWmicFinder)
);

$cores = (new CpuCoreCounter($finders))->getCount();
```

```php
// Use CPUInfo first & don't use Nproc
$finders = [
    new CpuInfoFinder(),
    new WindowsWmicFinder(),
    new HwLogicalFinder(),
];

$cores = (new CpuCoreCounter($finders))->getCount();
```

### Choosing only logical or physical finders

`FinderRegistry` provides two helpful entries:

- `::getDefaultLogicalFinders()`: gives an ordered list of finders that will
  look for the _logical_ CPU cores count.
- `::getDefaultPhysicalFinders()`: gives an ordered list of finders that will
  look for the _physical_ CPU cores count.

By default, when using `CpuCoreCounter`, it will use the logical finders since
it is more likely what you are looking for and is what is used by PHP source to
build the PHP binary.


### Checks what finders find what on your system

You have three scrips available that provides insight about what the finders
can find:

```shell
# Checks what each given finder will find on your system with details about the
# information it had.
make diagnose                                     # From this repository
./vendor/fidry/cpu-core-counter/bin/diagnose.php  # From the library
```

And:
```shell
# Execute all finders and display the result they found.
make execute                                     # From this repository
./vendor/fidry/cpu-core-counter/bin/execute.php  # From the library
```


### Debug the results found

You have 3 methods available to help you find out what happened:

1. If you are using the default configuration of finder registries, you can check
   the previous section which will provide plenty of information.
2. If what you are interested in is how many CPU cores were found, you can use
   the `CpuCoreCounter::trace()` method.
3. If what you are interested in is how the calculation of CPU cores available
   for parallelisation was done, you can inspect the values of `ParallelisationResult`
   returned by `CpuCoreCounter::getAvailableForParallelisation()`.


## Backward Compatibility Promise (BCP)

The policy is for the major part following the same as [Symfony's one][symfony-bc-policy].
Note that the code marked as `@private` or `@internal` are excluded from the BCP.

The following elements are also excluded:

- The `diagnose` and `execute` commands: those are for debugging/inspection purposes only
- `FinderRegistry::get*Finders()`: new finders may be added or the order of finders changed at any time


## License

This package is licensed using the MIT License.

Please have a look at [`LICENSE.md`](LICENSE.md).

[symfony-bc-policy]: https://symfony.com/doc/current/contributing/code/bc.html

---

## File: vendor/nette/utils/readme.md

[](https://doc.nette.org/en/utils)

[](https://packagist.org/packages/nette/utils)
[](https://github.com/nette/utils/actions)
[](https://coveralls.io/github/nette/utils?branch=master)
[](https://github.com/nette/utils/releases)
[](https://github.com/nette/utils/blob/master/license.md)


Introduction
------------

In package nette/utils you will find a set of useful classes for everyday use:

✅ [Arrays](https://doc.nette.org/utils/arrays)
✅ [Callback](https://doc.nette.org/utils/callback) - PHP callbacks
✅ [Filesystem](https://doc.nette.org/utils/filesystem) - copying, renaming, …
✅ [Finder](https://doc.nette.org/utils/finder) - finds files and directories
✅ [Floats](https://doc.nette.org/utils/floats) - floating point numbers
✅ [Helper Functions](https://doc.nette.org/utils/helpers)
✅ [HTML elements](https://doc.nette.org/utils/html-elements) - generate HTML
✅ [Images](https://doc.nette.org/utils/images) - crop, resize, rotate images
✅ [Iterables](https://doc.nette.org/utils/iterables) 
✅ [JSON](https://doc.nette.org/utils/json) - encoding and decoding
✅ [Generating Random Strings](https://doc.nette.org/utils/random)
✅ [Paginator](https://doc.nette.org/utils/paginator) - pagination math
✅ [PHP Reflection](https://doc.nette.org/utils/reflection)
✅ [Strings](https://doc.nette.org/utils/strings) - useful text functions
✅ [SmartObject](https://doc.nette.org/utils/smartobject) - PHP object enhancements
✅ [Type](https://doc.nette.org/utils/type) - PHP data type
✅ [Validation](https://doc.nette.org/utils/validators) - validate inputs

 

Installation
------------

The recommended way to install is via Composer:

```
composer require nette/utils
```

Nette Utils 4.1 is compatible with PHP 8.2 to 8.5.

 

[Support Me](https://github.com/sponsors/dg)
--------------------------------------------

Do you like Nette Utils? Are you looking forward to the new features?

[](https://github.com/sponsors/dg)

Thank you!

---

## File: vendor/nikic/php-parser/README.md

PHP Parser
==========

[](https://coveralls.io/github/nikic/PHP-Parser?branch=master)

This is a PHP parser written in PHP. Its purpose is to simplify static code analysis and
manipulation.

[**Documentation for version 5.x**][doc_master] (current; for running on PHP >= 7.4; for parsing PHP 7.0 to PHP 8.4, with limited support for parsing PHP 5.x).

[Documentation for version 4.x][doc_4_x] (supported; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.3).

Features
--------

The main features provided by this library are:

 * Parsing PHP 7, and PHP 8 code into an abstract syntax tree (AST).
   * Invalid code can be parsed into a partial AST.
   * The AST contains accurate location information.
 * Dumping the AST in human-readable form.
 * Converting an AST back to PHP code.
   * Formatting can be preserved for partially changed ASTs.
 * Infrastructure to traverse and modify ASTs.
 * Resolution of namespaced names.
 * Evaluation of constant expressions.
 * Builders to simplify AST construction for code generation.
 * Converting an AST into JSON and back.

Quick Start
-----------

Install the library using [composer](https://getcomposer.org):

    php composer.phar require nikic/php-parser

Parse some PHP code into an AST and dump the result in human-readable form:

```php
<?php
use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory;

$code = <<<'CODE'
<?php

function test($foo)
{
    var_dump($foo);
}
CODE;

$parser = (new ParserFactory())->createForNewestSupportedVersion();
try {
    $ast = $parser->parse($code);
} catch (Error $error) {
    echo "Parse error: {$error->getMessage()}\n";
    return;
}

$dumper = new NodeDumper;
echo $dumper->dump($ast) . "\n";
```

This dumps an AST looking something like this:

```
array(
    0: Stmt_Function(
        attrGroups: array(
        )
        byRef: false
        name: Identifier(
            name: test
        )
        params: array(
            0: Param(
                attrGroups: array(
                )
                flags: 0
                type: null
                byRef: false
                variadic: false
                var: Expr_Variable(
                    name: foo
                )
                default: null
            )
        )
        returnType: null
        stmts: array(
            0: Stmt_Expression(
                expr: Expr_FuncCall(
                    name: Name(
                        name: var_dump
                    )
                    args: array(
                        0: Arg(
                            name: null
                            value: Expr_Variable(
                                name: foo
                            )
                            byRef: false
                            unpack: false
                        )
                    )
                )
            )
        )
    )
)
```

Let's traverse the AST and perform some kind of modification. For example, drop all function bodies:

```php
use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;

$traverser = new NodeTraverser();
$traverser->addVisitor(new class extends NodeVisitorAbstract {
    public function enterNode(Node $node) {
        if ($node instanceof Function_) {
            // Clean out the function body
            $node->stmts = [];
        }
    }
});

$ast = $traverser->traverse($ast);
echo $dumper->dump($ast) . "\n";
```

This gives us an AST where the `Function_::$stmts` are empty:

```
array(
    0: Stmt_Function(
        attrGroups: array(
        )
        byRef: false
        name: Identifier(
            name: test
        )
        params: array(
            0: Param(
                attrGroups: array(
                )
                type: null
                byRef: false
                variadic: false
                var: Expr_Variable(
                    name: foo
                )
                default: null
            )
        )
        returnType: null
        stmts: array(
        )
    )
)
```

Finally, we can convert the new AST back to PHP code:

```php
use PhpParser\PrettyPrinter;

$prettyPrinter = new PrettyPrinter\Standard;
echo $prettyPrinter->prettyPrintFile($ast);
```

This gives us our original code, minus the `var_dump()` call inside the function:

```php
<?php

function test($foo)
{
}
```

For a more comprehensive introduction, see the documentation.

Documentation
-------------

 1. [Introduction](doc/0_Introduction.markdown)
 2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)

Component documentation:

 * [Walking the AST](doc/component/Walking_the_AST.markdown)
   * Node visitors
   * Modifying the AST from a visitor
   * Short-circuiting traversals
   * Interleaved visitors
   * Simple node finding API
   * Parent and sibling references
 * [Name resolution](doc/component/Name_resolution.markdown)
   * Name resolver options
   * Name resolution context
 * [Pretty printing](doc/component/Pretty_printing.markdown)
   * Converting AST back to PHP code
   * Customizing formatting
   * Formatting-preserving code transformations
 * [AST builders](doc/component/AST_builders.markdown)
   * Fluent builders for AST nodes
 * [Lexer](doc/component/Lexer.markdown)
   * Emulation
   * Tokens, positions and attributes
 * [Error handling](doc/component/Error_handling.markdown)
   * Column information for errors
   * Error recovery (parsing of syntactically incorrect code)
 * [Constant expression evaluation](doc/component/Constant_expression_evaluation.markdown)
   * Evaluating constant/property/etc initializers
   * Handling errors and unsupported expressions
 * [JSON representation](doc/component/JSON_representation.markdown)
   * JSON encoding and decoding of ASTs
 * [Performance](doc/component/Performance.markdown)
   * Disabling Xdebug
   * Reusing objects
   * Garbage collection impact
 * [Frequently asked questions](doc/component/FAQ.markdown)
   * Parent and sibling references

 [doc_3_x]: https://github.com/nikic/PHP-Parser/tree/3.x/doc
 [doc_4_x]: https://github.com/nikic/PHP-Parser/tree/4.x/doc
 [doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc

--- METRICS ---
- Files Extracted: 11
- Estimated Token Budget: ~16519 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/rectorphp/rector
