A collection of type-safe functional data structures

Overview

lamphpda

A collection of type-safe functional data structures

Aim

The aim of this library is to provide a collection of functional data structures in the most type safe way currently possible within the PHP ecosystem.

Main ideas

The two ideas which differentiate this from other functional libraries in PHP are:

Tools

We use Psalm as a type checker. It basically works as a compilation step, ensuring that all the types are aligned.

To benefit from this library, it is compulsory that your code runs through a Psalm check.

Content

The library provides some immutable data structures useful to write applications in a functional style. It models those structures using algebraic data types encoded in the following way:

Either as a working example

Let's consider the Either data structure. It represents the possibility of choice, the fact that one particular data could be one thing or another. It is encoded as a sum type with two constructors, called left and right

/**
 * @template A
 * @template B
 */
final class Either
{
    /** @var bool */
    private $isRight;

    /** @var A|null */
    private $leftValue;

    /** @var B|null */
    private $rightValue;

    /**
     * @param bool $isRight
     * @param A|null $leftValue
     * @param B|null $rightValue
     */
    private function __construct(bool $isRight, $leftValue = null, $rightValue = null)
    {
        $this->isRight = $isRight;
        $this->leftValue = $leftValue;
        $this->rightValue = $rightValue;
    }

    /**
     * @template C
     * @template D
     * @param C $value
     * @return Either<C, D>
     */
    public static function left($value): Either
    {
        return new self(false, $value);
    }

    /**
     * @template C
     * @template D
     * @param D $value
     * @return Either<C, D>
     */
    public static function right($value): Either
    {
        return new self(true, null, $value);
    }

The $isRight property is internal state used to keep track whether the specific value is a left or a right and is never exposed externally. The two public named constructors left and right are the only ways to build an Either object. The Either type is parametrised by two type variables, A and B, used respectively to track the type of left and right values. Written more synthetically, the type of left and right are

left :: C -> Either<C, D>
right :: D -> Either<C, D>

Now that we know how to build an Either, we need a way to consume it. The API exposes only one method to consume an Either, all other methods will need to use it internally. This method is called eval and allows us to consume the inner value of Either providing two callbacks, one for the left case, one for the right one.

    /**
     * @template C
     * @param callable(A): C $ifLeft
     * @param callable(B): C $ifRight
     * @return C
     */
    public function eval(
        callable $ifLeft,
        callable $ifRight
    ) {
        if ($this->isRight) {
            return $ifRight($this->rightValue);
        }

        return $ifLeft($this->leftValue);
    }
Comments
  • Maybe::eval() with lazy default?

    Maybe::eval() with lazy default?

    Maybe::eval() requires me to pass the default value for the nothing case immediately. Instead, I would like to evaluate it lazily, only when I really reach the nothing state. For that I would like to pass a callback accepting no arguments. Is it a feasible addition?

    opened by someniatko 23
  • CS update with PHP-CS-Fixer - WIP - just playing around

    CS update with PHP-CS-Fixer - WIP - just playing around

    This PR:

    • [x] Fix issues with PHP-CS-Fixer (1 rule per commit)
    • [x] Remove composer.lock from git.
    • [x] Use Grumphp through drupol/php-conventions
    • [ ] Investigate new PSalm issue => Issue found at https://github.com/marcosh/lamphpda/pull/8/commits/5b96f67e5d4f3f9f9af64411d9a42d5d4d0757c1#diff-c47877df3fa66c92b52cb2730c3b1876b765b1acf1339aa942138e1a6e6f85c4R21 - Is this a PSalm issue?
    opened by drupol 14
  • allow widening return type of Maybe::withDefault()

    allow widening return type of Maybe::withDefault()

    Consider having Maybe<string>, which you want to unwrap and default to null, for example.

    BTW, I think withDefault() is overly long and doesn't reveal the intent correctly: sounds like you "attach some default value to the Maybe", probably something like unwrap() could be a better name for this method. Or, perhaps eval() could be extended such that $ifJust callable is optional? The body of Maybe::eval() suggests that in past $ifJust was indeed optional.

    opened by someniatko 12
  • Use GitHub actions

    Use GitHub actions

    This PR:

    • [x] Enable Grumphp tasks
    • [x] Do not use Docker
    • [x] Use Github actions
    • [x] Normalize the composer.json, remove the version (never needed and confusing)
    • [x] Fix codestyle
    • [ ] Fix remaining PHPStan issues
    • [ ] Fix remaining Psalm issues

    As this is not merged yet, you can find the Github action log on my fork here: https://github.com/drupol/lamphpda/actions

    opened by drupol 6
  • ReaderMonad fixes?

    ReaderMonad fixes?

    Ciao Marco,

    I was wondering if such a patch would make sense:

    diff --git a/src/Instances/Reader/ReaderApplicative.php b/src/Instances/Reader/ReaderApplicative.php
    index 6a36d4a..afc02c3 100644
    --- a/src/Instances/Reader/ReaderApplicative.php
    +++ b/src/Instances/Reader/ReaderApplicative.php
    @@ -15,7 +15,9 @@ use Marcosh\LamPHPda\Reader;
     use Marcosh\LamPHPda\Typeclass\Applicative;
     
     /**
    - * @implements Applicative<ReaderBrand>
    + * @template E
    + *
    + * @implements Applicative<ReaderBrand<E>>
      *
      * @psalm-immutable
      */
    @@ -24,7 +26,6 @@ final class ReaderApplicative implements Applicative
         /**
          * @template A
          * @template B
    -     * @template E
          *
          * @param HK1<ReaderBrand<E>, callable(A): B> $f
          * @param HK1<ReaderBrand<E>, A> $a
    @@ -41,7 +42,6 @@ final class ReaderApplicative implements Applicative
         /**
          * @template A
          * @template B
    -     * @template E
          *
          * @param callable(A): B $f
          * @param HK1<ReaderBrand<E>, A> $a
    @@ -57,7 +57,6 @@ final class ReaderApplicative implements Applicative
     
         /**
          * @template A
    -     * @template E
          *
          * @param A $a
          *
    @@ -67,6 +66,11 @@ final class ReaderApplicative implements Applicative
          */
         public function pure($a): Reader
         {
    -        return Reader::reader(static fn ($_) => $a);
    +        return Reader::reader(
    +            /**
    +             * @param E $_
    +             */
    +            static fn ($_) => $a
    +        );
         }
     }
    diff --git a/src/Instances/Reader/ReaderApply.php b/src/Instances/Reader/ReaderApply.php
    index f09282d..d2f0451 100644
    --- a/src/Instances/Reader/ReaderApply.php
    +++ b/src/Instances/Reader/ReaderApply.php
    @@ -15,7 +15,9 @@ use Marcosh\LamPHPda\Reader;
     use Marcosh\LamPHPda\Typeclass\Apply;
     
     /**
    - * @implements Apply<ReaderBrand>
    + * @template E
    + *
    + * @implements Apply<ReaderBrand<E>>
      *
      * @psalm-immutable
      */
    @@ -24,10 +26,9 @@ final class ReaderApply implements Apply
         /**
          * @template A
          * @template B
    -     * @template E
          *
    -     * @param HK1<ReaderBrand, callable(A): B> $f
    -     * @param HK1<ReaderBrand, A> $a
    +     * @param HK1<ReaderBrand<E>, callable(A): B> $f
    +     * @param HK1<ReaderBrand<E>, A> $a
          *
          * @return Reader<E, B>
          *
    @@ -51,10 +52,9 @@ final class ReaderApply implements Apply
         /**
          * @template A
          * @template B
    -     * @template E
          *
          * @param callable(A): B $f
    -     * @param HK1<ReaderBrand, A> $a
    +     * @param HK1<ReaderBrand<E>, A> $a
          *
          * @return Reader<E, B>
          *
    diff --git a/src/Instances/Reader/ReaderFunctor.php b/src/Instances/Reader/ReaderFunctor.php
    index 447199f..aba1993 100644
    --- a/src/Instances/Reader/ReaderFunctor.php
    +++ b/src/Instances/Reader/ReaderFunctor.php
    @@ -15,7 +15,9 @@ use Marcosh\LamPHPda\Reader;
     use Marcosh\LamPHPda\Typeclass\Functor;
     
     /**
    - * @implements Functor<ReaderBrand>
    + * @template E
    + *
    + * @implements Functor<ReaderBrand<E>>
      *
      * @psalm-immutable
      */
    @@ -24,10 +26,9 @@ final class ReaderFunctor implements Functor
         /**
          * @template A
          * @template B
    -     * @template E
          *
          * @param callable(A): B $f
    -     * @param HK1<ReaderBrand, A> $a
    +     * @param HK1<ReaderBrand<E>, A> $a
          *
          * @return Reader<E, B>
          *
    @@ -38,6 +39,9 @@ final class ReaderFunctor implements Functor
             $readerA = Reader::fromBrand($a);
     
             return Reader::reader(
    +            /**
    +             * @param E $env
    +             */
                 static fn ($env) => $f($readerA->runReader($env))
             );
         }
    diff --git a/src/Instances/Reader/ReaderMonad.php b/src/Instances/Reader/ReaderMonad.php
    index 0d7e813..da75edf 100644
    --- a/src/Instances/Reader/ReaderMonad.php
    +++ b/src/Instances/Reader/ReaderMonad.php
    @@ -15,7 +15,9 @@ use Marcosh\LamPHPda\Reader;
     use Marcosh\LamPHPda\Typeclass\Monad;
     
     /**
    - * @implements Monad<ReaderBrand>
    + * @template E
    + *
    + * @implements Monad<ReaderBrand<E>>
      *
      * @psalm-immutable
      */
    @@ -24,10 +26,9 @@ final class ReaderMonad implements Monad
         /**
          * @template A
          * @template B
    -     * @template E
          *
    -     * @param HK1<ReaderBrand, callable(A): B> $f
    -     * @param HK1<ReaderBrand, A> $a
    +     * @param HK1<ReaderBrand<E>, callable(A): B> $f
    +     * @param HK1<ReaderBrand<E>, A> $a
          *
          * @return Reader<E, B>
          *
    @@ -41,10 +42,9 @@ final class ReaderMonad implements Monad
         /**
          * @template A
          * @template B
    -     * @template E
          *
    -     * @param HK1<ReaderBrand, A> $a
    -     * @param callable(A): HK1<ReaderBrand, B> $f
    +     * @param HK1<ReaderBrand<E>, A> $a
    +     * @param callable(A): HK1<ReaderBrand<E>, B> $f
          *
          * @return Reader<E, B>
          *
    @@ -55,6 +55,9 @@ final class ReaderMonad implements Monad
             $readerA = Reader::fromBrand($a);
     
             return Reader::reader(
    +            /**
    +             * @param E $env
    +             */
                 static fn ($env) => Reader::fromBrand($f($readerA->runReader($env)))->runReader($env)
             );
         }
    @@ -62,10 +65,9 @@ final class ReaderMonad implements Monad
         /**
          * @template A
          * @template B
    -     * @template E
          *
          * @param callable(A): B $f
    -     * @param HK1<ReaderBrand, A> $a
    +     * @param HK1<ReaderBrand<E>, A> $a
          *
          * @return Reader<E, B>
          *
    @@ -78,7 +80,6 @@ final class ReaderMonad implements Monad
     
         /**
          * @template A
    -     * @template E
          *
          * @param A $a
          *
    

    But then, these new psalm issues are raised:

    $ ./vendor/bin/psalm --no-cache
    Target PHP version: 7.4 (inferred from composer.json)
    Scanning files...
    Analyzing files...
    
    ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░EEEE░░░░░░░░░░ 60 / 81 (74%)
    ░░░░░░░░░░░░░░░░░░░░░
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderApplicative.php:33:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed>, B:fn-marcosh\lamphpda\typeclass\apply::apply as mixed>' for Marcosh\LamPHPda\Typeclass\Apply::apply is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderApplicative::apply 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed, B:fn-marcosh\lamphpda\instances\reader\readerapplicative::apply as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderApplicative.php:49:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed>, B:fn-marcosh\lamphpda\typeclass\functor::map as mixed>' for Marcosh\LamPHPda\Typeclass\Functor::map is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderApplicative::map 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed, B:fn-marcosh\lamphpda\instances\reader\readerapplicative::map as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderApplicative.php:63:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed>, A:fn-marcosh\lamphpda\typeclass\applicative::pure as mixed>' for Marcosh\LamPHPda\Typeclass\Applicative::pure is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderApplicative::pure 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderApplicative as mixed, A:fn-marcosh\lamphpda\instances\reader\readerapplicative::pure as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, A>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderApply.php:33:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderApply as mixed>, B:fn-marcosh\lamphpda\typeclass\apply::apply as mixed>' for Marcosh\LamPHPda\Typeclass\Apply::apply is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderApply::apply 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderApply as mixed, B:fn-marcosh\lamphpda\instances\reader\readerapply::apply as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderApply.php:59:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderApply as mixed>, B:fn-marcosh\lamphpda\typeclass\functor::map as mixed>' for Marcosh\LamPHPda\Typeclass\Functor::map is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderApply::map 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderApply as mixed, B:fn-marcosh\lamphpda\instances\reader\readerapply::map as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderFunctor.php:33:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderFunctor as mixed>, B:fn-marcosh\lamphpda\typeclass\functor::map as mixed>' for Marcosh\LamPHPda\Typeclass\Functor::map is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderFunctor::map 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderFunctor as mixed, B:fn-marcosh\lamphpda\instances\reader\readerfunctor::map as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderMonad.php:33:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed>, B:fn-marcosh\lamphpda\typeclass\apply::apply as mixed>' for Marcosh\LamPHPda\Typeclass\Apply::apply is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderMonad::apply 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed, B:fn-marcosh\lamphpda\instances\reader\readermonad::apply as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderMonad.php:49:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed>, B:fn-marcosh\lamphpda\typeclass\monad::bind as mixed>' for Marcosh\LamPHPda\Typeclass\Monad::bind is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderMonad::bind 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed, B:fn-marcosh\lamphpda\instances\reader\readermonad::bind as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderMonad.php:72:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed>, B:fn-marcosh\lamphpda\typeclass\functor::map as mixed>' for Marcosh\LamPHPda\Typeclass\Functor::map is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderMonad::map 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed, B:fn-marcosh\lamphpda\instances\reader\readermonad::map as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, B>
    
    
    ERROR: ImplementedReturnTypeMismatch - src/Instances/Reader/ReaderMonad.php:86:16 - The inherited return type 'Marcosh\LamPHPda\HK\HK1<Marcosh\LamPHPda\Brand\ReaderBrand<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed>, A:fn-marcosh\lamphpda\typeclass\applicative::pure as mixed>' for Marcosh\LamPHPda\Typeclass\Applicative::pure is different to the implemented return type for Marcosh\LamPHPda\Instances\Reader\ReaderMonad::pure 'Marcosh\LamPHPda\Reader<E:Marcosh\LamPHPda\Instances\Reader\ReaderMonad as mixed, A:fn-marcosh\lamphpda\instances\reader\readermonad::pure as mixed>' (see https://psalm.dev/123)
         * @return Reader<E, A>
    
    
    ------------------------------
    10 errors found
    ------------------------------
    
    Checks took 4.49 seconds and used 58.837MB of memory
    Psalm was able to infer types for 100% of the codebase
    
    opened by drupol 3
  • Converting `list<Maybe<T>>` to `Maybe<list<T>>`

    Converting `list>` to `Maybe>`

    Inspired by Promise:all() from JavaScript.

    Could a function which takes list of Maybes, and if ALL of them are just, returns a single Maybe with list of wrapped values, however if ANY of them is nothing, returns Maybe::nothing, be of any use? Or maybe it already exists in some more generic form?

    opened by someniatko 2
  • Add documentation

    Add documentation

    Hello,

    As I can likely understand terms as Applicative, Functor, SemiGroup which are mathematical terms we can found on schema https://en.wikipedia.org/wiki/Monoid

    I don't understand what are all terms and specially what is Brand and HK1. So may be adding some documentation about mathematical terms on the project should help people understands the theorical concepts.

    opened by matyo91 2
  • Implements `Reader` monad.

    Implements `Reader` monad.

    This PR:

    • [x] Implements the Reader Monad.
    • [ ] Has no Psalm errors

    Keep in mind that I'm doing this to learn monads, it might contains inconsistencies - please bear with me.

    opened by drupol 1
  • Issue #17: Base set of files for `Identity` monad/data-type

    Issue #17: Base set of files for `Identity` monad/data-type

    Hey,

    I did this thing, mostly by copying pasting the Maybe monad and modifying things here and there.

    Could you please clarify the following questions?

    • [x] Am I in the right direction? Looks like yes!
    • [x] Unit or Identity? Identity
    • [x] Name of the static constructor method? wrap

    Documentation:

    • Unit: https://pursuit.purescript.org/packages/purescript-prelude/5.0.1/docs/Data.Unit#t:Unit
    • Identity: https://pursuit.purescript.org/packages/purescript-identity/5.0.0/docs/Data.Identity#t:Identity

    Context:

    I'm pretty new to Monad, I'm doing this mostly to learn them. Please bear with me :)

    opened by drupol 1
  • add `Identity` data type

    add `Identity` data type

    Define Identity data structure

    • [x] Functor instance
    • [x] Apply instance
    • [x] Applicative instance
    • [x] Monad instance
    • [x] Foldable instance
    • [x] Traversable instance
    opened by marcosh 1
  • Add `Writer` data type

    Add `Writer` data type

    Define Writer data structure defined as https://github.com/marcosh/lamphpda/blob/master/src-old/Writer.php

    • [ ] Functor instance
    • [ ] Apply instance
    • [ ] Applicative instance
    • [ ] Monad instance
    opened by marcosh 1
  • Implements `semigroup` instances

    Implements `semigroup` instances

    This PR implements:

    • [x] AndSemigroup
    • [x] OrSemigroup
    • [x] StringSemigroup
    • [x] IntAdditionSemigroup
    • [x] IntMultiplicationSemigroup

    Could you please let me know if this is the right way? I'll wait for your feeback before going further.

    opened by drupol 0
  • Test for typeclass laws

    Test for typeclass laws

    Add generic tests to check that laws are respected by typeclass instances

    • [ ] Functor
    • [ ] Apply
    • [ ] Applicative
    • [ ] Monad
    • [ ] Foldable
    • [ ] Traversable
    opened by marcosh 0
  • Add `Const` data type

    Add `Const` data type

    Add Const data structure as defined in https://hackage.haskell.org/package/base-4.15.0.0/docs/Control-Applicative.html#t:Const

    • [ ] Functor instance
    • [ ] Apply instance
    • [ ] Applicative instance
    • [ ] Foldable instance
    • [ ] Traversable instance
    opened by marcosh 0
  • Add `MonadCatch` typeclass

    Add `MonadCatch` typeclass

    Define MonadCatch typeclass defined as in https://hackage.haskell.org/package/exceptions-0.10.4/docs/Control-Monad-Catch.html#t:MonadCatch

    This might require to change MonadThrow and specifically update the instance for Maybe

    • [ ] IO
    • [ ] Maybe
    • [ ] Either
    • [ ] LinkedList
    • [ ] Identity
    opened by marcosh 0
Releases(v1.2.0)
Owner
Marco Perone
Marco Perone
Collection of value objects that represent the types of the PHP type system

sebastian/type Collection of value objects that represent the types of the PHP type system. Installation You can add this library as a local, per-proj

Sebastian Bergmann 1.1k Dec 29, 2022
The easiest way to match data structures like JSON/PlainText/XML against readable patterns. Sandbox:

PHP Matcher Library created for testing all kinds of JSON/XML/TXT/Scalar values against patterns. API: PHPMatcher::match($value = '{"foo": "bar"}', $p

Coduo 774 Dec 31, 2022
Tentative Extra Data Structures for php

Teds Introduction Teds is a another collection of data structures. (Tentative Extra Data Structures) Installation This extension requires php 8.0 or n

Tyson Andre 26 Nov 21, 2022
JsonQ is a simple, elegant PHP package to Query over any type of JSON Data

php-jsonq JsonQ is a simple, elegant PHP package to Query over any type of JSON Data. It'll make your life easier by giving the flavour of an ORM-like

Nahid Bin Azhar 834 Dec 25, 2022
📦 "PHP type names" contains the list of constants for the available PHP data types.

PHP type names PHP type names ?? Description Simple library containing the list of constants for the available PHP data types. Use those constant type

♚ PH⑦ de Soria™♛ 4 Dec 15, 2022
A Magento implementation for validating JSON Structures against a given Schema

Zepgram JsonSchema A Magento implementation for validating JSON Structures against a given Schema with support for Schemas of Draft-3 or Draft-4. Base

Benjamin Calef 1 Nov 5, 2021
laminas-xml2json provides functionality for converting XML structures to JSON

laminas-xml2json This package is considered feature-complete, and is now in security-only maintenance mode, following a decision by the Technical Stee

Laminas Project 13 Dec 28, 2022
Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics (functional) API that doesn't cause vendor lock-in.

Metrics Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics API that doesn't cau

Benjamin Eberlei 311 Nov 20, 2022
A simple functional programming library for PHP

bingo-functional A simple functional programming library for PHP. Requirement(s) PHP 7 or higher Rationale PHP, a language not commonly associated wit

Lochemem Bruno Michael 52 Sep 28, 2022
Small library providing some functional programming tools for PHP, based on Rambda

Functional library for PHP. Features: set of useful functions helpful in functional programming all functions are automatically curried every array ca

Wojciech Nawalaniec 5 Jun 16, 2022
N2Web turns your Notion HTML export into a fully functional static website

Notion2Web N2Web turns your Notion HTML export into a fully functional static website. What is Notion? Notion is an online tool. But I can't tell you

Lars Lehmann 15 Nov 23, 2022
Simple libary for functional programing paradigm with arrays.

rodrigodornelles/php-array-lib simple libary for functional programing paradigm with arrays Features Test driven development style (TDD) PHP version c

null 10 Nov 28, 2022
WARNING! This software is currently non-functional. - A system which makes installing Jexactyl far, far easier.

Jexactyl Assistant A system which makes installing Jexactyl far, far easier. WARNING ?? This software is currently in heavy alpha testing and WILL NOT

Jexactyl 7 Nov 14, 2022
Sitepackage for TYPO3 CMS that adheres to the recommended standards, maps all conceivable functional areas and contains examples for common use cases.

TYPO3 CMS Sitepackage This sitepackage sticks as closely as possible to the recommended standard and maps all conceivable functional areas. There are

Eric Bode 3 Dec 18, 2022
The Current US Version of PHP-Nuke Evolution Xtreme v3.0.1b-beta often known as Nuke-Evolution Xtreme. This is a hardened version of PHP-Nuke and is secure and safe. We are currently porting Xtreme over to PHP 8.0.3

2021 Nightly Builds Repository PHP-Nuke Evolution Xtreme Developers TheGhost - Ernest Allen Buffington (Lead Developer) SeaBeast08 - Sebastian Scott B

Ernest Buffington 7 Aug 28, 2022
Make your PHP arrays sweet'n'safe

Mess We face a few problems in our PHP projects Illogical type casting (PHP's native implementation is way too "smart") Pointless casts like array =>

Artem Zakirullin 192 Nov 28, 2022
BetterWPDB - Keeps you safe and sane when working with custom tables in WordPress.

BetterWPDB - Keeps you safe and sane when working with custom tables in WordPress.

Snicco 21 Dec 15, 2022
This is the US hardened version of PHP-Nuke Titanium and is secure and safe

This is the US hardened version of PHP-Nuke Titanium and is secure and safe. Built on PHP Version 7.4.30 - Forums - Blogs - Projects - Advanced Site Map - Web Links - Groups - Advanced Theme Support - Downloads - Advertising - Network Advertising - Link Back System - FAQ - Bookmark Vault - Private Virtual Cemetery - Loan Amortization - Image Hosting

Ernest Allen Buffington (The Ghost) 12 Dec 25, 2022