Skip to content

Commit

Permalink
Add CodeExporter, fixes #30
Browse files Browse the repository at this point in the history
  • Loading branch information
Merlin committed Mar 16, 2024
1 parent 613ead1 commit c582cf5
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,28 @@ try {
}
```

## Literal code expressions

```php
use Brick\VarExporter\VarExporter;
use Brick\Code;

echo VarExporter::export([
'literal_expression' => Code::create("$app_root", ". '/../private'");
], VarExporter::ALLOW_CODE);
```

This code will output:

```php
[
'literal_expression' => $app_root
. '/../private',
]
```

Also, you can implement CodeInterface in your custom code.

## Limitations

- Exporting internal classes other than `stdClass` and `Closure`, and classes implementing `__set_state()` (most notably DateTime classes) is currently not supported. `VarExporter` will throw an `ExportException` if it finds one.
Expand Down
29 changes: 29 additions & 0 deletions src/Code.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);
namespace Brick\VarExporter;

final class Code implements CodeInterface {

/**
* @var string[]
*/
private array $lines;

/**
* @param string[] $lines
*/
private function __construct(array $lines) {
$this->lines = $lines;
}

public static function create(string ...$lines): self {
return new self($lines);
}

public function toLines(): array
{
return $this->lines;
}

}
13 changes: 13 additions & 0 deletions src/CodeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);
namespace Brick\VarExporter;

interface CodeInterface {

/**
* @return string[]
*/
public function toLines(): array;

}
9 changes: 9 additions & 0 deletions src/Internal/GenericExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ final class GenericExporter
*/
public $trailingCommaInArray;

/**
* @psalm-readonly
*
* @var bool
*/
public $allowCode;

/**
* @psalm-readonly
*
Expand All @@ -83,6 +90,7 @@ final class GenericExporter

public function __construct(int $options, int $indentLevel = 0)
{
$this->objectExporters[] = new ObjectExporter\CodeExporter($this);
$this->objectExporters[] = new ObjectExporter\StdClassExporter($this);

if (! ($options & VarExporter::NO_CLOSURES)) {
Expand Down Expand Up @@ -113,6 +121,7 @@ public function __construct(int $options, int $indentLevel = 0)
$this->inlineScalarList = (bool) ($options & VarExporter::INLINE_SCALAR_LIST);
$this->closureSnapshotUses = (bool) ($options & VarExporter::CLOSURE_SNAPSHOT_USES);
$this->trailingCommaInArray = (bool) ($options & VarExporter::TRAILING_COMMA_IN_ARRAY);
$this->allowCode = (bool) ($options & VarExporter::ALLOW_CODE);

$this->indentLevel = $indentLevel;
}
Expand Down
30 changes: 30 additions & 0 deletions src/Internal/ObjectExporter/CodeExporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Brick\VarExporter\Internal\ObjectExporter;

use Brick\VarExporter\Internal\ObjectExporter;
use Brick\VarExporter\CodeInterface;

/**
* Handles instances of LiteralInterface.
*
* @internal This class is for internal use, and not part of the public API. It may change at any time without warning.
*/
final class CodeExporter extends ObjectExporter
{

public function supports(\ReflectionObject $reflectionObject): bool
{
return $this->exporter->allowCode
&& $reflectionObject->implementsInterface(CodeInterface::class);
}

public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds): array
{
assert($object instanceof CodeInterface);
return $object->toLines();
}

}
5 changes: 5 additions & 0 deletions src/VarExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ final class VarExporter
*/
public const INLINE_SCALAR_LIST = 1 << 7;

/**
* Any value implementing CodeInterface will print a literal expression.
*/
public const ALLOW_CODE = 1 << 8;

/**
* @deprecated Please use INLINE_SCALAR_LIST instead.
*/
Expand Down

0 comments on commit c582cf5

Please sign in to comment.