Quant PHP Library

website·Indexed 31 days ago

https://quant-php.dev

An all-purpose library for PHP 8.2 designed to facilitate and extend PHP language features. It provides a low-level API through quant/core, offering contracts, base classes, and commonly-used functionality, as well as phpstan extensions via quant/phpstan.

Tokens
3.8K
Snippets
21
Records
26
Agent score
49%

What's inside Quant

  1. Overview of quant/core package

    quant/core is a low-level API package that provides contracts, base classes, and commonly-used functionality for the quant ecosystem. It is bundled with the main quant package but can be installed separately.
  2. Overview of the quant PHP library

    quant is a shared utility library for PHP applications, derived from functionality proven useful in projects like conjoon. It requires PHP version 8.2 or higher.
  3. Implement a strongly typed list using AbstractList

    The AbstractList<T> class in the Quant\Core namespace provides a base for creating strongly typed lists. It implements ArrayAccess, Iterator, Countable, Arrayable, and Equatable. To implement a custom list, you must extend AbstractList and implement the getType() method to return the class name of the items the list maintains. Items can be added using the array shorthand syntax ($list[] = $item); adding an item of the wrong type will throw a TypeError.
    #[Getter] #[Setter]
    class Entity 
    {
        use AccessorTrait;
        public function __construct(private string $value) {}
    }
    
    class EntityList extends AbstractList 
    {
        public function getType(): string
        {
            return Entity::class;
        }
        
        protected function compareItems(mixed $a, mixed $b): bool
        {
            if (!($a instanceof Entity) && !($b instanceof Entity)) {
                return false;
            }
            return $a->getValue() === $b->getValue();
        }
    }
    
    // Usage
    $list = new EntityList();
    $list[] = new Entity("1");
    
    // Using the static factory method
    $listC = EntityList::make(new Entity("3"), new Entity("4"));
  4. Install and register quant/phpstan for PHPStan

    The quant/phpstan extension provides PHPStan support for the quant framework. To install and automatically register the extension, use the phpstan extension-installer.
    composer require --dev phpstan/extension-installer && \
      composer require --dev quant/phpstan
  5. Apply setter guards during object construction

    Since constructor property promotion bypasses standard setters, use the applyProperties(array $args) method within the constructor to trigger the apply{PropertyName} guards. The $args array is treated positionally, where the key corresponds to the parameter index in the constructor signature.
    use Quant\Core\Trait\AccessorTrait;
    use Quant\Core\Attribute\Setter;
    
    class Target {
        use AccessorTrait;
    
        public function __construct(
            private string $a, // index 0
            #[Setter] private string $b // index 1
        ) {
            // Apply guard for $b using its positional index
            $this->applyProperties([1 => $b]);
            
            // Alternatively, apply all constructor arguments:
            // $this->applyProperties(func_get_args());
        }
    
        protected function applyB(string $value): mixed {
            return $value;
        }
    }
  6. Automate getters and setters using AccessorTrait

    The AccessorTrait (namespace Quant\Core\Trait) provides automated getter and setter methods for object properties marked with the #[Getter] and #[Setter] attributes. This allows developers to avoid writing boilerplate accessors. The trait supports properties defined in the class body as well as those defined via constructor property promotion.
    use Quant\Core\Trait\AccessorTrait;
    use Quant\Core\Attribute\Setter;
    use Quant\Core\Attribute\Getter;
    
    class Employee {
        use AccessorTrait;
    
        #[Setter] #[Getter]
        private string $name = "John Smith";
    
        public function __construct(
            #[Getter]
            private string $empId
        ) {}
    }
    
    $employee = new Employee("87i-dsd-89z-978");
    echo $employee->getEmpId(); // "87i-dsd-89z-978"
    $employee->setName("Thomas Anderson")->getName(); // "Thomas Anderson"
  7. Implement the Arrayable interface to provide array representations

    The Arrayable interface in the Quant\Core\Contract namespace is used to indicate that a class instance can be represented as an array. To implement this contract, a class must provide a toArray() method that returns an array representation of the instance.
    use Quant\Core\Contract\Arrayable;
    
    class Point implements Arrayable {
        public function __construct(
            private float $x,
            private float $y
        ) {}
    
        public function toArray(): array
        {
            return [
                "x" => $this->x,
                "y" => $this->y
            ];
        }
    }
  8. Install individual quant component packages

    If you do not need the full library, you can install specific packages from the quant project by referencing their individual package names.
    composer require quant/core
  9. Example: Implementing Comparable for a Money class

    This example demonstrates how to implement the Comparable interface for a Money class by comparing the primary amount first and then the cents to determine the total order.
    #[Getter]
    class Money implements Comparable {
        use AccessorTrait;
        
        public function __construct(
            private int $amount,
            private int $cents
        ) {}
    
        public function compareTo(Comparable $b): int
        {
            if (!($b instanceof Money)) {
                // Note: The source returns false, but the interface expects int
                throw new 
    InvalidArgumentException("Cannot compare Money with non-Money object");
            }
            
            $aAmount = $this->getAmount();
            $bAmount = $b->getAmount();
            
            $aCents = $this->getCents();
            $bCents = $b->getCents();
            
            // Compare primary amount
            $c = ($aAmount === $bAmount ? 0 : ($aAmount < $bAmount ? -1 : 1));
            
            // If amounts are equal, compare cents
            return $c !== 0 ? $c : ($aCents < $bCents ? -1 : ($aCents > $bCents ? 1 : 0));
        }
    }
  10. Reference for Quant\Core\Contract\Arrayable

    The Arrayable interface defines the requirement for a class to be convertible to an array.
    namespace Quant\Core\Contract;
    
    interface Arrayable {
        /**
         * Returns an array representation of the implementing class' instance
         * @return array<int, mixed>
         */
        public function toArray(): array;
    }
  11. Implement total ordering with the Comparable interface

    The Comparable interface in the Quant\Core\Contract namespace allows objects to implement a total order. This is achieved by implementing the compareTo method, which must return an integer indicating the relative order of two objects.

    Expected behavior for compareTo(Comparable $b):

    • Returns -1 if the current object is less than $b.
    • Returns 0 if the current object is equal to $b.
    • Returns 1 if the current object is greater than $b.

    Implementation requirements:

    • Reflexive: $a->compareTo($a) must be 0.
    • Antisymmetric: If $a->compareTo($b) <= 0 and $b->compareTo($a) <= 0, then $a->compareTo($b) must be 0.
    • Transitive: If $a->compareTo($b) <= 0 and $b->compareTo($c) <= 0, then $a->compareTo($c) must be <= 0.
    • Consistency with Equatable: If an object also implements Equatable, then $a->equals($b) must imply $a->compareTo($b) === 0.
    namespace Quant\Core\Contract;
    
    interface Comparable {
        public function compareTo(Comparable $obj): int;
    }