Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Type Laravel Package

php-standard-library/type

Runtime type validation for PHP using “Parse, Don’t Validate”: coerce and assert unstructured input into well-typed data. Useful for APIs, configs, and user input with clear parsing rules, assertions, and predictable failures.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require php-standard-library/type
    

    Ensure your composer.json targets PHP 8.1+ (required for named arguments and strict types).

  2. First Use Case: API Request Validation Replace manual type checks in FormRequest or controller methods:

    use PhpStandardLibrary\Type\Type;
    
    public function store(Request $request) {
        $data = $request->validate([
            'name' => 'required|string',
            'tags' => 'sometimes|array',
        ]);
    
        // Use package for runtime assertions
        Type::assertString($data['name']);
        Type::assertArray($data['tags'] ?? null, true); // Allow null
    }
    
  3. Where to Look First

    • Core Methods: Browse PhpStandardLibrary\Type\Type for is*(), assert*(), and coerce*() methods. Example: Type::isNonEmptyArray(), Type::assertCallable(), Type::coerceToInt().
    • Documentation: PHP Standard Library Docs (check for type package specifics).
    • Tests: Clone the repo and run phpunit to see real-world usage patterns.

Implementation Patterns

Usage Patterns

  1. Validation Workflows

    • API Layer: Use assert*() methods to fail fast on malformed input.
      public function update(Request $request) {
          $payload = json_decode($request->getContent(), true);
          Type::assertNonEmptyArray($payload, 'Invalid payload format');
          // Proceed with validated data
      }
      
    • Service Layer: Combine with Laravel’s Validator for hybrid validation.
      Validator::extend('valid_type', function ($attribute, $value, $parameters) {
          return Type::isString($value) || Type::isInt($value);
      });
      
  2. Data Transformation

    • Coercion: Convert dynamic input to strict types before processing.
      $userId = Type::coerceToInt($request->input('user_id'), 0); // Default to 0
      $isActive = Type::coerceToBool($request->input('active')); // "1" → true
      
  3. DTO/Value Object Safety

    • Enforce type contracts in constructors:
      public function __construct(
          private string $name,
          private array $metadata = []
      ) {
          Type::assertString($name);
          Type::assertArray($metadata);
      }
      
  4. Legacy Code Modernization

    • Replace nested is_* checks with fluent assertions:
      // Before
      if (!is_array($config) || empty($config) || !isset($config['timeout'])) {
          throw new InvalidArgumentException();
      }
      
      // After
      Type::assertNonEmptyArray($config);
      Type::assertArrayKeyExists('timeout', $config);
      

Integration Tips

  • Laravel-Specific:
    • Form Requests: Use in withValidator() to add custom rules:
      public function withValidator($validator) {
          $validator->after(function ($validator) {
              Type::assertNonEmptyArray($this->all()['tags'] ?? null);
          });
      }
      
    • Service Providers: Bind type-aware factories:
      $this->app->bind(ValidatedData::class, function ($app) {
          return new ValidatedData(
              Type::coerceToInt($app['request']->input('limit'), 10)
          );
      });
      
  • Testing:
    • Mock Type methods in unit tests to isolate validation logic:
      Type::shouldReceive('assertString')->once()->with($input);
      
  • Performance:
    • Cache results for repeated checks (e.g., in loops):
      $isValid = cache()->remember("type_check_{$value}", now()->addHours(1), function () {
          return Type::isString($value);
      });
      

Gotchas and Tips

Pitfalls

  1. Null Handling Quirks

    • Type::isArray(null) returns false (unlike is_array(null) which returns true).
    • Use Type::isArray($value, true) to allow null values.
    • Tip: Document nullability expectations in method signatures:
      /**
       * @param array|null $value Allows null arrays.
       */
      public function process(array|null $value) { ... }
      
  2. Recursive Type Checks

    • Methods like isArrayOf() or isObjectOf() may not handle deeply nested structures as expected.
    • Workaround: Use Type::deepValidate() (if available) or implement custom recursion:
      function assertNestedArrays(array $data, int $depth = 0): void {
          if ($depth > 5) throw new \RuntimeException('Max depth exceeded');
          foreach ($data as $item) {
              Type::assertArray($item);
              assertNestedArrays($item, $depth + 1);
          }
      }
      
  3. False Positives in Assertions

    • Type::assertCallable() may fail on valid closures or strings (e.g., "strlen").
    • Tip: Use Type::isCallable() for detection, then assert separately:
      if (!Type::isCallable($callback)) {
          throw new \InvalidArgumentException('Callable expected');
      }
      
  4. Laravel-Specific Conflicts

    • Namespace Collisions: Avoid naming custom classes Type or Assert to prevent conflicts.
    • Validation Overrides: Ensure package methods don’t clash with Laravel’s Validator rules.

Debugging

  1. Unexpected Failures

    • Debug Tip: Log the actual type before asserting:
      \Log::debug('Value type:', [
          'value' => $value,
          'type' => gettype($value),
          'var_dump' => var_export($value, true),
      ]);
      Type::assertString($value);
      
    • Common culprits: UTF-8 BOMs in strings, serialized objects, or stdClass instances.
  2. Performance Bottlenecks

    • Profile Tip: Use Laravel Telescope or Blackfire to identify slow Type::* calls in hot paths.
    • Optimization: Replace runtime checks with static analysis (PHPStan) where possible.
  3. Edge Cases

    • Floats vs. Integers: Type::isInt(1.0) may return false (use Type::isNumeric() if needed).
    • Resources: Type::isResource() is rarely useful in Laravel (prefer is_resource() for files/DB handles).

Extension Points

  1. Custom Type Guards

    • Extend the package by creating wrapper methods:
      class AppType {
          public static function isLaravelCollection(mixed $value): bool {
              return $value instanceof \Illuminate\Support\Collection;
          }
      }
      
    • Tip: Use traits to avoid code duplication across services.
  2. Integration with Laravel Validation

    • Create a custom validation rule for reusable type checks:
      use Illuminate\Validation\Rule;
      
      class TypeRule extends Rule {
          public function passes($attribute, $value) {
              return Type::isNonEmptyArray($value);
          }
      }
      
      Usage:
      $request->validate([
          'tags' => ['required', new TypeRule],
      ]);
      
  3. Coercion Strategies

    • Override default coercion behavior (e.g., for coerceToInt):
      $value = Type::coerceToInt($input, function ($val) {
          return (int) str_replace(',', '', $val); // Custom parsing
      });
      
  4. Null Object Pattern

    • Use Type::coerceToNull() to handle missing/empty values:
      $config = Type::coerceToNull($request->input('config'), []);
      if ($config === null) {
          // Handle default case
      }
      

Configuration Quirks

  • No Built-in Config: The package is dependency-free; all behavior is method-based.
  • Laravel-Specific: No config/type.php—customize via service providers or helper classes.
  • Type Hinting: Prefer PHP 8.1+ union types (e.g., string|int) over runtime checks where possible.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui