Bag PHP Library

repository·main·Indexed 41 days ago

https://github.com/beacon-hq/bag

A PHP 8.3+ library for creating immutable, strongly-typed value objects. Bag provides type safety, validation, and data casting, featuring deep integration with Laravel Collections and Validation. It supports automatic type casting for scalars, Enums, and Date/Time objects, as well as explicit casting via attributes like #[Cast]. Key features include composability with nested objects, a specialized Bag\Collection for immutable sets of value objects, and support for computed properties.

Tokens
64.9K
Snippets
215
Records
291
Agent score
48%

What's inside Bag

  1. What is Bag and when to use Value Objects?

    main

    Bag is a library for creating immutable, strongly typed Value Objects in PHP.

    When to use them: You should use Bag Value Objects in place of regular associative arrays. This allows you to enforce type safety and immutability, making your data handling safer and more predictable.

    Key Features:

    • Immutability & Strong Typing: Data cannot be changed after instantiation, and types are strictly enforced.
    • Built-in Validation & Casting: Ensures data conforms to expected formats.
    • Composability: You can nest Bag value objects and collections to build complex, hierarchical data structures.
  2. What is Bag?

    main

    Bag is a PHP library designed to help you create immutable and strongly typed value objects. It provides a safer and more predictable way to work with data by encapsulating it within objects rather than using regular arrays.

    Key features include:

    • Immutability & Strong Typing: Ensures data cannot be changed after instantiation and enforces type safety.
    • Composability: Allows you to nest Bag value objects and collections to build complex, hierarchical data structures.
    • Built-in Validation & Casting: Provides mechanisms to validate and cast data during object creation.
  3. What is Bag and when to use it

    main

    Bag is a library for creating immutable, strongly-typed value objects in PHP 8.3+.

    Use Bag value objects in place of regular arrays to enforce type safety and immutability. Bag provides features like value casting (input and output), collection support, composability (nesting objects and collections), and built-in validation.

    Key Characteristics:

    • Immutable & Strongly typed: Once created, the data cannot be changed.
    • Composable: You can nest Bag value objects and collections within each other.
    • Framework Agnostic: While it works with any PHP project, it has deep integration with Laravel, using standard Laravel Collections and Validation, and supports automatic injection of Bag objects into Laravel controllers with validation.
  4. Key features and capabilities of Bag

    main

    Bag is a lightweight PHP library for working with immutable value objects. It provides several core capabilities for data handling:

    • Value Casting: Supports both inbound and outbound casting, including support for nested Bag objects.
    • Name Mapping: Allows mapping property names at both the class and property levels.
    • Validation: Integrated validation support.
    • Collections: Support for collections of Value Objects, specifically using Bag\Collection (an immutable-safe variant of Laravel Collections).
    • Conversions: Ability to convert objects to Bag instances and wrap output arrays or JSON.
    • Laravel Integration: Supports Eloquent Casting and Laravel Controller Injection.
    • Hidden Properties: Ability to hide specific properties when transforming an object to an array or JSON.
    • Variadic Support: Supports variadic arguments during value object creation.
  5. Core features of Bag

    main

    Bag is a lightweight PHP library for working with immutable value objects. Key features include:

    • Value Casting: Supports casting for both incoming and outgoing values, including nested Bag objects.
    • Name Mapping: Allows mapping property names at both the class and property levels for both input and output.
    • Validation: Integrated support for validating value object data.
    • Collections: Support for collections of value objects, specifically using Bag\Collection (an immutable-safe variant of Laravel Collections).
    • Object Conversion: Ability to convert standard objects to Bag instances.
    • Output Wrapping: Support for wrapping output arrays or JSON.
    • Laravel Integration: Includes support for Eloquent Casting and Laravel Controller Injection.
    • Hidden Properties: Ability to hide specific properties when transforming the object to an array or JSON.
  6. Key features of Bag value objects

    main

    Bag provides several advanced features for managing data through value objects:

    • Value Casting: Supports both inbound (input) and outbound (transforming to array/JSON) casting, including support for nested Bag objects.
    • Name Mapping: Allows mapping property names at both the class and individual property levels for both inbound and outbound data.
    • Validation: Integrated support for validating data within the value object.
    • Collections: Support for collections of value objects. While it works with standard Laravel Collections, it provides Bag\Collection as an immutable-safe variant.
    • Object to Bag Conversion: Ability to convert existing objects into Bag instances.
    • Wrapping: Ability to wrap output arrays or JSON into Bag objects.
    • Hidden Properties: Support for hiding specific properties when transforming the object to an array or JSON.
    • Variadic Support: Supports the use of variadic arguments during value object creation.
  7. Core features and capabilities of Bag

    main

    Bag is a lightweight PHP library for working with immutable value objects. It provides several key features for data handling:

    • Value Casting: Supports both inbound and outbound casting, including support for nested Bag objects.
    • Name Mapping: Allows mapping property names at both the class and property levels for inbound and outbound data.
    • Validation: Integrated support for validating value object data.
    • Collections: Support for collections of value objects, specifically using Bag\Collection (an immutable-safe variant of Laravel Collections).
    • Object Conversion: Ability to convert existing objects into Bag instances.
    • Output Wrapping: Support for wrapping output arrays or JSON.
    • Laravel Integration: Includes support for Eloquent Casting, Laravel Controller Injection, and an Artisan command for scaffolding.
    • Hidden Properties: Ability to hide specific properties when transforming a Bag to an array or JSON.
  8. Core features of Bag value objects

    main

    Bag is a lightweight PHP library for working with immutable, type-safe value objects. Key capabilities include:

    • Value Casting: Supports both inbound and outbound casting, including nested Bag objects.
    • Name Mapping: Allows mapping property names at both the class and property levels for inbound and outbound data.
    • Validation: Integrated support for validating value object data.
    • Collections: Native support for collections of value objects, specifically using Bag\Collection for immutable-safe operations.
    • Object Conversion: Ability to convert standard objects into Bag instances.
    • Output Wrapping: Supports wrapping output arrays or JSON.
    • Laravel Integration: Provides support for Eloquent Casting and Laravel Controller Injection.
    • Hidden Properties: Ability to hide specific properties when transforming a Bag to an array or JSON.
  9. Automatic casting of input values

    main

    If no Cast attribute is provided, Bag automatically attempts to cast input values to the type hinted in the property constructor.

    Supported automatic casts include:

    • Scalar types: int, float, bool, string.
    • Date/Time: \Carbon\CarbonImmutable, \Carbon\Carbon, \DateTimeImmutable, and \DateTime (parsed using PHP date/time formats).
    • Bag objects: Arrays are cast to Bag objects.
    • Laravel Collections: Values are wrapped via collect($value).
    • BackedEnums: Casts the value using Enum::from($value).
    • UnitEnums: Casts the value by name (e.g., Enum::{$value}).
    • Laravel Models: Casts an ID to a model instance using Model::findOrFail($value).

    Warning: Automatic date/time parsing can be loose. For example, passing a time string like 12:34:56 to a CarbonImmutable property will result in a CarbonImmutable object with the current date and that specific time. To enforce a specific input format, use the #[Cast(DateTime::class, format: '...', strictMode: true)] attribute instead.

    use Bag\Bag;
    use Carbon\CarbonImmutable;
    
    class MyValue extends Bag {
        public function __construct(
            public CarbonImmutable $dateOfBirth,
        ) {
        }
    }
    
    // Automatically casts string to CarbonImmutable
    MyValue::from([
        'dateOfBirth' => '1984-05-31',
    ]);
  10. How the Output Collection Pipeline works

    main

    The OutputCollectionPipeline is specifically designed for transforming Bag collections into arrays or JSON. It is triggered by calling toArray(), toJson(), json_encode(), or unwrapped() on a Collection object.

    The process is simple:

    1. The collection data is retrieved.
    2. The output is passed through a wrap step (if converting to an array or JSON) to ensure the collection structure is correctly represented in the final output.
  11. Automatic Type Casting in Bag

    main

    If the input value matches the property type (including union types), it is used as-is. Otherwise, Bag automatically casts values to the defined type for all scalar types and the following:

    • Bag objects
    • \Bag\Collection and \Illuminate\Support\Collection objects
    • \DateTimeInterface objects (including \DateTime, \DateTimeImmutable, \Carbon\Carbon, and \Carbon\CarbonImmutable) using standard PHP Date/Time formats.
    • Enums

    Recommendation: Use \Carbon\CarbonImmutable for all date/time properties.

  12. Handle JSON strings specifically with Bag::FROM_JSON

    main

    By default, Bag attempts to transform JSON strings. To override the default JSON handling or to explicitly differentiate between standard strings and JSON strings, use the special type Bag::FROM_JSON within the #[Transforms] attribute.

    This is useful when you want to ensure a specific method is only called when the input is intended to be parsed as JSON.

    use Bag\Bag;
    
    class MyValue extends Bag
    {
        #[Transforms(Bag::FROM_JSON)]
        protected static function fromJsonString(string $json): array
        {
            return json_decode($json, true, 512, JSON_THROW_ON_ERROR);
        }
    }