feolius / hell2shape
Generate PHPStan type annotations from var_dump output
Requires
- php: ^8.3
- symfony/console: ^5.1|^6.0|^7.0|^8.0
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.4
- symplify/easy-coding-standard: ^13.0
README
Generate PHPStan type annotations from var_dump output
A CLI tool that analyzes PHP var_dump() output and generates PHPStan-compatible type annotations, helping you add type hints to legacy code or complex data structures.
Use It Online
🌐 Try hell2shape in your browser - No installation required. Works locally in your browser, no data transferred -- thanks to php-wasm.
Installation
Option 1: Install via Composer (Recommended for Programmatic Usage)
composer require --dev feolius/hell2shape
This allows you to use hell2shape both programmatically in your code and via CLI.
Option 2: Download PHAR (Standalone Executable)
Download the latest hell2shape.phar from the releases page and use it directly:
# Download the PHAR curl -L https://github.com/Feolius/hell2shape/releases/latest/download/hell2shape.phar -o hell2shape.phar # Make it executable chmod +x hell2shape.phar # Use it php -r 'var_dump($myArray);' | ./hell2shape.phar
Option 3: Use cpx
php -r 'var_dump($myArray);' | cpx feolius/hell2shape
Requirements:
- PHP 8.3 or higher
Usage
Programmatic Usage
Use hell2shape directly in your PHP code to generate type annotations:
use Feolius\Hell2Shape\Hell2Shape; use Feolius\Hell2Shape\Generator\GeneratorConfig; use Feolius\Hell2Shape\Generator\KeyQuotingStyle; // Simple usage with default config (generates PSR-5 doc-comment format) $data = ['name' => 'John', 'age' => 30]; $shape = Hell2Shape::generate($data); // Result: /** // * array{ // * name: string, // * age: int, // * } // */ // Without doc-comment wrapper $config = GeneratorConfig::withoutDocComment(); $shape = Hell2Shape::generate($data, $config); // Result: array{ // name: string, // age: int, // } // Single-line output without doc-comment $config = GeneratorConfig::withoutDocComment(indentSize: 0); $shape = Hell2Shape::generate($data, $config); // Result: array{name: string, age: int} // With custom formatting (doc-comment is default) $config = new GeneratorConfig( keyQuotingStyle: KeyQuotingStyle::SingleQuotes, indentSize: 2, ); $shape = Hell2Shape::generate($data, $config); // Result: /** // * array{ // * 'name': string, // * 'age': int, // * } // */
CLI Usage
Pipe any var_dump() output to hell2shape:
# From a PHP script php script.php | vendor/bin/hell2shape # From a one-liner php -r 'var_dump(["name" => "John", "age" => 30]);' | vendor/bin/hell2shape
Output Example
Input (var_dump):
array(2) {
["name"]=>
string(4) "John"
["age"]=>
int(30)
}
Output (PHPStan type with doc-comment - default):
/** * array{ * name: string, * age: int, * } */
Output (without doc-comment using --no-doc-comment):
array{
name: string,
age: int,
}
Options
--no-doc-comment
Disable PSR-5 doc-comment wrapper around the output (by default, output is wrapped in /** */)
# Default: with doc-comment wrapper hell2shape # Output: /** # * array{...} # */ # Without doc-comment wrapper hell2shape --no-doc-comment # Output: array{...}
--indent / -i
Control indentation for multi-line output (default: 4 spaces)
# Single-line output hell2shape --indent=0 # 2-space indentation hell2shape -i 2 # Default 4-space indentation hell2shape
--quotes
Control key quoting style in array shapes
# No quotes (default) hell2shape --quotes=none # Output: array{name: string} # Single quotes hell2shape --quotes=single # Output: array{'name': string} # Double quotes hell2shape --quotes=double # Output: array{"name": string}
--class / -c
Control how class names are formatted (default: unqualified)
# Unqualified - just the class name (default) hell2shape --class=uqn # Output: User # Qualified - with namespace hell2shape -c qn # Output: App\Models\User # Fully qualified - with leading backslash hell2shape --class=fqn # Output: \App\Models\User
Features
- ✅ Scalar types (int, string, bool, float, null)
- ✅ Arrays and nested arrays
- ✅ Array shapes with optional keys
- ✅ Objects (class names)
- ✅ stdClass objects as object shapes
- ✅ Lists with union types
- ✅ Complex nested structures
- ✅ Configurable formatting
Examples
Simple Array
php -r 'var_dump(["id" => 1, "name" => "Alice"]);' | hell2shape
Output:
/** * array{ * id: int, * name: string, * } */
Nested Structure
php -r 'var_dump(["user" => ["name" => "Bob", "roles" => ["admin", "user"]]]);' | hell2shape
Output:
/** * array{ * user: array{ * name: string, * roles: list<string>, * }, * } */
Without Doc-Comment
php -r 'var_dump(["id" => 1, "active" => true]);' | hell2shape --no-doc-comment
Output:
array{
id: int,
active: bool,
}
Single-line Output
php -r 'var_dump(["id" => 1, "active" => true]);' | hell2shape --no-doc-comment --indent=0
Output:
array{id: int, active: bool}
Optional Keys
When arrays have different structures, hell2shape marks missing keys as optional:
array{
id: int,
name: string,
email?: string
}
Object Types
php -r 'namespace App\Models; class User {} var_dump(new User());' | hell2shape
Output (default - unqualified):
/** User */
With qualified names:
php -r 'namespace App\Models; class User {} var_dump(new User());' | hell2shape -c qn
Output:
/** App\Models\User */
With fully qualified names:
php -r 'namespace App\Models; class User {} var_dump(new User());' | hell2shape --class=fqn
Output:
/** \App\Models\User */
Limitations
⚠️ Important: This tool provides a starting point for type annotations, not a complete solution.
- var_dump doesn't show all possible values, only the current state
- Union types are inferred from visible data only
- You should review and refine the generated types based on your actual usage
- Empty arrays are typed as
array(notlist<mixed>)
Development
# Run tests vendor/bin/phpunit # Run PHPStan vendor/bin/phpstan analyse # Run code style checks vendor/bin/ecs check
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.