{"id":20254760,"url":"https://github.com/chippyash/strong-type","last_synced_at":"2025-04-11T00:05:00.524Z","repository":{"id":18821678,"uuid":"22036663","full_name":"chippyash/Strong-Type","owner":"chippyash","description":"Strong (or hard) type support for basic PHP types. Cut down on input error. Avoid PHP 7 upgrade issues","archived":false,"fork":false,"pushed_at":"2018-07-04T21:39:16.000Z","size":880,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T00:04:40.145Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chippyash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-20T15:56:40.000Z","updated_at":"2020-12-05T11:37:14.000Z","dependencies_parsed_at":"2022-08-21T03:40:22.582Z","dependency_job_id":null,"html_url":"https://github.com/chippyash/Strong-Type","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FStrong-Type","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FStrong-Type/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FStrong-Type/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FStrong-Type/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chippyash","download_url":"https://codeload.github.com/chippyash/Strong-Type/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248317708,"owners_count":21083528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T10:34:46.491Z","updated_at":"2025-04-11T00:05:00.508Z","avatar_url":"https://github.com/chippyash.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chippyash/Type\n\n## Quality Assurance\n\n![PHP 5.6](https://img.shields.io/badge/PHP-5.6-blue.svg)\n![PHP 7](https://img.shields.io/badge/PHP-7-blue.svg)\n[![Build Status](https://travis-ci.org/chippyash/Strong-Type.svg?branch=master)](https://travis-ci.org/chippyash/Strong-Type)\n[![Test Coverage](https://codeclimate.com/github/chippyash/Strong-Type/badges/coverage.svg)](https://codeclimate.com/github/chippyash/Strong-Type/coverage)\n[![Code Climate](https://codeclimate.com/github/chippyash/Strong-Type/badges/gpa.svg)](https://codeclimate.com/github/chippyash/Strong-Type)\n\nThe above badges represent the current development branch.  As a rule, I don't push\n to GitHub unless tests, coverage and usability are acceptable.  This may not be\n true for short periods of time; on holiday, need code for some other downstream\n project etc.  If you need stable code, use a tagged version. Read 'Further Documentation'\n and 'Installation'.\n \nPlease note that developer support for PHP5.3 was withdrawn at version 4.0.0 of this library.\nIt may be that the code will continue to run for you at later versions, but you must\nascertain that for yourself. If you need support for PHP 5.3, please use a version\n`\u003e=3,\u003c4`\n\nAlso note that developer support for PHP5.4 \u0026 5.5 was withdrawn at version 5.0.0 of this library.\nIt may be that the code will continue to run for you at later versions, but you must\nascertain that for yourself. If you need support for PHP 5.4 or 5.5, please use a version\n`\u003e=4,\u003c5`\n \nGMP support is tested on the Travis-ci build servers for PHP V5.6 as that is the only\nversion that stable gmp support is available for.   \n\nSee the [Test Contract](https://github.com/chippyash/Strong-Type/blob/master/docs/Test-Contract.md) in the docs directory.\n\n## What?\n\nProvides strong type implementations of base PHP types.  Adds some 'missing'\nnumeric types.\n\n### Types supported\n\n*  BoolType\n*  DigitType\n*  FloatType\n*  ComplexType\n*  IntType\n*  NaturalIntType\n*  WholeIntType\n*  RationalType\n*  StringType\n\nThe library is released under the [GNU GPL V3 or later license](http://www.gnu.org/copyleft/gpl.html)\n\n## Why?\n\nOne of the joys of PHP is its loose typing, but there are situations, particularly\nin large or complex systems where you want to guarantee that method parameters are\nwhat you want them to be. PHP's type hinting extends to a few basic native types\nsuch as arrays and hard typing to class names.  For the rest you end up having to\nput a lot of boiler plate in your methods just to ensure that when you expect a\nfloat for instance, you get one (or use hhvm ;-) ).  This library addresses the \nissue for some basic PHP types plus some extensions for what could be considered \n'missing' types.\n\nThe most common use case for this library is as a strong type hinter for your public methods:\n\n\u003cpre\u003e\n    \n    public function myFunc(StringType $str, IntType $ival);\n    \n\u003c/pre\u003e\n\nBingo: your function expects a StringType and and an IntType and nothing else!\n\nThe primary purpose of strong typing in this context is to *guard your public\nmethods against unwarranted side effects*.  Unwrap the native type at the point\nof use.\n\nThe secondary use case is for when you want to start using some missing types fromPHP,\nin particular Rational (fractions) and Complex numeric types.  I've built a reasonably \ncomprehensive Mathematical Matrix library based on the numeric types from this library.\n\n### PHP 7 warning\n\nPHP 7 introduces type hinting for [native types](https://blog.engineyard.com/2015/what-to-expect-php-7)\nbut the problem is that you are going to get an automatic conversion or caste.  Not what I'd\nexpect. In the meantime, use this StongType library to harden your application.\n\nThat said, once you get into the swing of using the basic types, you'll find them most amenable to being passed\naround and used interchangeably with PHP native types, primarily because they support a \\__toString() method and \n\\__invoke() which proxies to the get() method.\n\n\u003cpre\u003e\n    \n    public function myFunc(StringType $str, IntType $ival)\n    {\n        echo $str;\n        $foo = \"The amount is {$ival}\";\n        $n = 2 * $ival();\n    }\n    \n\u003c/pre\u003e\n\n## When\n\nThe current library covers basic data types plus some extensions.\n\nIf you want more, either suggest it, or better still, fork it and provide a pull request.\n\nSee [The Matrix Packages](http://the-matrix.github.io/packages/) for other packages from Chippyash\n\n## How\n\n### Coding Basics\n\n#### Very simple way\n\nThis is how we use it in everyday work to ensure that our calls to some function\nis conformant:\n\n\u003cpre\u003e\nfunction foo(FloatType $foo) {...}\n$myFoo = foo(new FloatType(1);\n\u003c/pre\u003e\n\nNB. The integer `1` is going to get converted into a float `1.0` but that is ok \n because our method `foo()` expects a FloatType and with PHPs current type hinting\n can enforce it.\n\n#### For those that have the stamina\n\nCreate a type via the Type Factory:\n\n\u003cpre\u003e\n    use Chippyash\\Type\\TypeFactory;\n    $str = TypeFactory::create('string','foo');\n    //or\n    $str = TypeFactory::createString('foo');\n\n    $int = TypeFactory::createInt(2);\n    //or\n    $int = Typefactory::create('int', 2);\n\n    //some types can take two parameters\n    $rat = TypeFactory::create('rational', 2, 3);\n\u003c/pre\u003e\n\netc, etc\n\nSupported type tags are:\n\n*  bool (or boolean)\n*  digit\n*  float (or double)\n*  complex\n*  int (or integer)\n*  natural\n*  whole\n*  rational\n*  string\n\nCreate one directly:\n\n\u003cpre\u003e\n    use Chippyash\\Type\\Number\\Complex\\ComplexType;\n    use Chippyash\\Type\\Number\\Rational\\Rationaltype;\n    use Chippyash\\Type\\String\\DigitType;\n    use Chippyash\\Type\\String\\StringType;\n    use Chippyash\\Type\\Number\\FloatType;\n    use Chippyash\\Type\\Number\\IntType;\n    $c = new ComplexType(new RationalType(new IntType(-2), new IntType(1)), new RationalType(new IntType(3), new IntType(4));\n    $d = new DigitType(34);\n    $s = new StringType('foo');\n    $d2 = new DigitType('34foo'); // == '34'\n    $r = new RationalType(new IntType(1), new IntType(2));\n\u003c/pre\u003e\n\netc, etc\n\nCreate a complex type via the Complex Type Factory (n.b. the Type Factory uses\nthis)\n\n\u003cpre\u003e\n    use Chippyash\\Type\\Number\\Complex\\ComplexTypeFactory;\n    $c = ComplexTypeFactory::create('13-2.67i');\n    //same as\n    $c = ComplexTypeFactory::fromString('13-2.67i');\n\n    $c = ComplexTypeFactory::create(2.4, new IntType(-6));\n    $c = ComplexTypeFactory::create(2, -61.78);\n    $c = ComplexTypeFactory::create(new FloatType(2), -61.78);\n    //i.e. any pair of numeric, intType, FloatType or RationalType values can be used to create\n    //a complex type via the factory\n\u003c/pre\u003e\n\nCreate a rational type via the Rational Type Factory (n.b. the Type Factory uses\nthis, but using it directly may give you finer grain control in some circumstances.)\n\n\u003cpre\u003e\n    use Chippyash\\Type\\Number\\Rational\\RationalTypeFactory;\n    $r = RationalTypeFactory::create(M_1_PI);    //results in 25510582/80143857\n    $r = RationalTypeFactory::fromFloat(M_1_PI); //ditto\n    $r = RationalTypeFactory::fromFloat(M_1_PI, 1e-5); //results in 113/355\n    $r = RationalTypeFactory::fromFloat(M_1_PI, 1e-17);  //results in 78256779/245850922\n\n    $r = RationalTypeFactory::create('2/3');\n    //same as\n    $r = RationalTypeFactory::fromString('2/3');\n\u003c/pre\u003e\n\nRationalTypeFactory::fromFloat obeys the current setting of RationalTypeFactory::$defaultTolerance.  The default\nvalue is 1e-15.  You can change this by calling RationalTypeFactory::setDefaultFromFloatTolerance() at the beginning \nof your program.\n\nAll types support the TypeInterface:\n\n*  get() - return the value as a PHP native type (if possible)\n*  set($value) - set the value\n*  \\__toString() - Magic toString method. Return value as a string\n*  \\__invoke() - Proxy to get(), allows you to write $c() instead of $c-\u003eget()\n\nNumeric types, that is IntType, WholeIntType, NaturalIntType, FloatType, RationalType\nand ComplexType support the NumericTypeInterface which defines the methods\n\n*  negate(): negate the number - NB Negation is will throw a \\BadMethodCallException for WholeInt and NaturalInt types as they cannot be negative\n*  asComplex(): returns a complex real representation of the number (e.g. 2+0i).  For\ncomplex types, simply clones the existing object.\n*  asRational(): returns rational representation of the number.  For rational types, simply clones the existing object.\n*  asIntType(): returns number caste as IntType.  For IntType, simply clones the existing objeoct.\n*  asFloatType(): returns number caste as FloatType.  For FloatType, simply clones the existing objeoct.\n*  abs(): return the absolute value of the number\n*  sign(): return sign of number: -1 == negative, 0 == zero, 1 == positive\n\nIntTypes support two additional methods:\n\n*  factors(): array: returns a sorted array of factors of the number\n*  primeFactors(): array: returns \\[primeFactor =\u003e exponent,...\\] i.e the primeFactor =\u003e number of times it occurs\n\nAdditionally, the RationalType supports the RationalTypeInterface:\n\n*  numerator() - return the integer value numerator\n*  denominator() - return the integer value denominator\n\nNB, AbstractRationalType amends the set() method to proxy to setFromTypes(), i.e. calling RationalType::set()\nrequires the same parameters as setFromTypes()\n\nAdditionally the ComplexType supports the ComplexTypeInterface:\n\n*  r() - return the real part as a RationalType\n*  i() - return the imaginary part as a RationalType\n*  isZero() - Is this number equal to zero?\n*  isReal() - Is this number a real number?  i.e. is it in form n+0i\n*  isGuassian() - Is this number Gaussian, i.e r \u0026 i are both equivalent to integers\n*  conjugate() - Return conjugate of this number\n*  modulus() - Return the modulus, also known as absolute value or magnitude of this number\n*  theta() - Return the angle (sometimes known as the argument) of the number when expressed in polar notation\n*  radius() - Return the radius (sometimes known as Rho) of the number when expressed in polar notation\n*  asPolar() - Returns complex number expressed in polar form i.e. an array \\[radius, theta\\]\n*  polarQuadrant() - Returns the polar quadrant for the complex number\n*  polarString() - Return complex number expressed as a string in polar form i.e. r(cosθ + i⋅sinθ)\n\nNB, ComplexType amends the set() method to proxy to SetFromTypes, i.e. calling ComplexType::set()\nrequires the same parameters as setFromTypes().\n\nThere is no PHP native equivalent for a ComplexType, therefore the get() method proxies to the\n\\__toString() method and returns something in the form [-]a(+|-)bi e.g. '-2+3.6i' except where\nThe ComplexType-\u003eisReal() in which case get() will return a float or an int.  If you need to disambiguate\nthen use ComplexType::toFloat() which will throw an exception if the number is not real.\n\nPolar form complex numbers are supported by the polar methods in ComplexType and also by the\nComplexTypeFactory::fromPolar(RationalType $radius, RationalType $theta) method.\n\n### Support for GMP extension - V2 onwards only\n\nThe library automatically recognises the availability of the gmp extension and\nwill use it for int, rational and complex types.  \n\nThere is no gmp support for WholeIntType, NaturalIntType or FloatType.\n\n- WholeIntType and NaturalIntType creation via the TypeFactory will return GMPIntType.\n    - The validation for whole and natural numbers is ignored - they are treated as integers\n- FloatType creation via the TypeFactory will return a GMPRationalType.\n\nYou can force the library to use PHP native types by calling\n\n\u003cpre\u003e\n    use Chippyash\\Type\\RequiredType; \n    RequiredType::getInstance()-\u003eset(RequiredType::TYPE_NATIVE);\n\u003c/pre\u003e\n\nat the start of your code. This will in turn call the setNumberType methods on the\nother factories, so you don't need to do that\n\nIf you want to get the gmp typed value of a number you can call its gmp() method.\n\n\u003cpre\u003e\n    //assuming we are running under gmp\n    $i = TypeFactory::create('int', 2); //returns GMPIntType\n    $i = TypeFactory::create('whole', -1); //returns GMPIntType\n    $i = TypeFactory::create('natural', 0); //returns GMPIntType\n    $gmp = $i-\u003egmp(); //returns resource or GMP object depending on PHP version\n\n    $r = TypeFactory::create('rational', 2, 3); //returns GMPRationalType\n    $r = TypeFactory::create('float', 2/3); //returns GMPRationalType\n    $gmp = $i-\u003egmp(); //returns resource or GMP object depending on PHP version\n\n    $r = TypeFactory::create('rational', 2, 3); //returns GMPRationalType\n    $gmp = $r-\u003egmp(); //returns array of gmp types, [numerator, denominator]\n\n    $c = TypeFactory::create('complex', '2+3i'); //returns GMPComplexType\n    $gmp = $c-\u003egmp(); //returns array of gmp types, [[num,den],[num,den]] i.e. [r,i]\n\u003c/pre\u003e\n\nAll GMP types support the GMPInterface, so in addition to having the gmp() method,\nthey will also have:\n\n*  public function asGMPIntType() Return number as GMPIntType number. Will return floor(n/d) for rational types    \n*  public function asGMPComplex() : Return the number as a GMPComplex number i.e. n+0i\n*  public function asGMPRational(): Return number as GMPRational number.\n\nTrying to keep track of what types you are actually instantiating is made much easier if\nyou use the type factories, as they know which types to create.  **Therefore if\nyou want your code to be runnable as PHP native or GMP, use the factories to\ncreate your numeric types.**\n\n## Further documentation\n\nYou can find the [API documentation here](http://chippyash.github.io/Strong-Type)\n\n[Test Contract](https://github.com/chippyash/Strong-Type/blob/master/docs/Test-Contract.md) in the docs directory.\n\nCheck out [ZF4 Packages](http://zf4.biz/packages?utm_source=github\u0026utm_medium=web\u0026utm_campaign=blinks\u0026utm_content=strongtype) for more packages\n\n### UML\n\n![class diagram](https://github.com/chippyash/Strong-Type/blob/master/docs/strong-type-class.png)\n\n## Changing the library\n\n1.  fork it\n2.  write the test\n3.  amend it\n4.  do a pull request\n\nFound a bug you can't figure out?\n\n1.  fork it\n2.  write the test\n3.  do a pull request\n\nNB. Make sure you rebase to HEAD before your pull request\n\nOr - raise an issue ticket.\n\n## Where?\n\nThe library is hosted at [Github](https://github.com/chippyash/Strong-type). It is\navailable at [Packagist.org](https://packagist.org/packages/chippyash/strong-type)\n\n### Installation\n\nInstall [Composer](https://getcomposer.org/)\n\n#### For production\n\nUse V5 unless you have a strong reason not to.\n\u003cpre\u003e\n    \"chippyash/strong-type\": \"\u003e=5.0.0,\u003c6\"\n\u003c/pre\u003e\n\nV5 branch is the default, no further development of ealier versions will take place.\n \n#### For development\n\nClone this repo, and then run Composer in local repo root to pull in dependencies\n\n\u003cpre\u003e\n    git clone git@github.com:chippyash/Strong-Type.git StrongType\n    cd StrongType\n    composer update\n\u003c/pre\u003e\n\nTo run the tests:\n\n\u003cpre\u003e\n    cd StrongType\n    vendor/bin/phpunit -c test/phpunit.xml test/\n\u003c/pre\u003e\n\n## License\n\nThis software library is released under the [BSD 3 Clause license](https://opensource.org/licenses/BSD-3-Clause)\n\nThis software library is Copyright (c) 2014-2018, Ashley Kitson, UK\n\nThis software library contains code items that are: \n\n- Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)\n- released under the New BSD License\n\nIn particular the code items are:\n\n- elements of Chippyash\\Type\\String\\DigitType\n- all of Chippyash\\Zend\\ErrorHandler\n\nNone of the contained code items breaks the overriding license, or vice versa,  as \nfar as I can tell. So as long as you stick to BSD license(or comaptible) then you are\nsafe. If at all unsure, please seek appropriate advice.\n\nIf the original copyright owners of the included code items object to this inclusion, \nplease contact the author.\n\nThis library is supported by \u003ca href=\"https://www.jetbrains.com\"\u003e\u003cimg src=\"https://github.com/chippyash/Strong-Type/raw/master/img/JetBrains.png\" alt=\"Jetbrains\" style=\"height: 200px;vertical-align: middle;\"\u003e\u003c/a\u003e\nwho provide their IDEs to Open Source developers.\n\n\n## History\n\nV0...  pre releases\n\nV1.0.0 Original release\n\nV1.0.1 Remove requirement for zendfilter package to reduce dependency footprint\n\n       Add NumericTypeInterface to support other usages of library\n\nV1.0.2 Add conjugate method to complex type\n\n       rebase wholeInt and naturalInt type on intType\n\nV1.0.3 Add modulus method to complex type\n\nV1.0.4 Fix RationalTypefactory::fromFloat not recognising zero\n\nV1.0.5 Add negate() method to numeric types\n\nV1.0.6 Add isReal() method for complex numbers\n\n        add toFloat() method for complex numbers if number isReal()\n\nV1.0.7 Add toComplex() method for numeric types\n\nV1.0.8 Add abs() method for numeric types\n\nV1.0.9 Add asRational, asFloatType and asIntType methods for numeric types. Rename toComplex -\u003e asComplex method\n\nV1.0.10 Refactor Typefactory to use as... methods\n\nV1.0.11 Ensure isolation of type parts in as... methods\n\nV1.1.0 Add Polar form complex number support\n        \n        move interfaces to separate folder\n\nV1.1.1 Remove hard coded tolerance levels to fromFloat. Use default 1e-15 instead.\n\nV1.1.2 Ensure clone clones inner objects correctly\n\nV1.1.3 Refactor in preparation for supporting GMP types\n\nV2.0.0 Add GMP support\n\nV2.0.1 Additional gmp type checking\n\nV2.0.2 update Zend dependencies\n\nV2.0.3 fix tests breaking if GMP not installed - will skip properly\n\nV2.0.4 add homepage to composer.json definition\n\nV2.0.5 small amend to fix complex creation problem for calculator\n\nV2.0.6 update phpunit to ~V4.3.0\n\nV2.0.7 add test contract\n\nV2.0.8 when GMP support enabled:\n\n- WholeIntType and NaturalIntType creation via the TypeFactory will return GMPIntType.\n- FloatType creation via the TypeFactory will return a GMPRationalType.\n- RationalType creation via the TypeFactory will return a GMPRationalType.\n- ComplexType creation via the TypeFactory will return a GMPComplexType.\n\nV2.0.9 fix merge\n\nV2.1.0 downgrade library to support PHP5.3 - too many people still using it!\n\nV2.1.1 fix PHP5.3 unit tests\n\nV2.1.2 remove dependency on Zend\\StdLib\n\nV2.1.3 refactor for code cleanliness\n\nV2.1.4 deprecate Typefactory::setNumberType() method\n\nV3.0.0 BC Break: Rename namespace from chippyash\\Type to Chippyash\\Type\n\nV3.0.1 add link to packages\n\nV3.0.2 verify PHP7 compatibility\n\nV4.0.0 BC Break: end PHP5.3 support. build script changes\n\nV4.0.1 update composer - forced by packagist composer.json format change\n\nV5.0.0 BC Break: end of support for PHP \u003c5.6\n\nV5.1.0 Change of license from GPL V3 to BSD 3 Clause \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fstrong-type","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchippyash%2Fstrong-type","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fstrong-type/lists"}