chippyash/strong-type

强类型支持。当你绝对需要知道你得到的是什么时

5.1.0 2018-07-04 21:38 UTC

This package is auto-updated.

Last update: 2024-09-22 23:05:49 UTC


README

质量保证

PHP 5.6 PHP 7 Build Status Test Coverage Code Climate

上面的徽章代表当前的开发分支。通常情况下,除非测试、覆盖率和使用性可接受,否则我不会将代码推送到GitHub。在假期、需要为其他下游项目编写代码等情况下,这可能在短时间内不成立。如果您需要稳定的代码,请使用标记版本。请阅读‘进一步文档’和‘安装’。

请注意,自该库的4.0.0版本起,已撤回对PHP5.3的开发者支持。代码在以后的版本中可能仍将继续运行,但您必须自行确认。如果您需要PHP 5.3的支持,请使用版本 >=3,<4

此外,请注意,自该库的5.0.0版本起,已撤回对PHP5.4和5.5的开发者支持。代码在以后的版本中可能仍将继续运行,但您必须自行确认。如果您需要PHP 5.4或5.5的支持,请使用版本 >=4,<5

在PHP V5.6的Travis-ci构建服务器上测试了GMP支持,因为这是唯一提供稳定GMP支持的版本。

请参阅文档目录中的 测试合同

什么?

提供PHP基本类型的强类型实现。添加了一些“缺少”的数字类型。

支持的类型

  • BoolType
  • DigitType
  • FloatType
  • ComplexType
  • IntType
  • NaturalIntType
  • WholeIntType
  • RationalType
  • StringType

该库根据 GNU GPL V3或更高版本许可 发布。

为什么?

PHP的乐趣之一就是它的松散类型,但在某些情况下,尤其是在大型或复杂的系统中,您希望保证方法参数正是您想要的。PHP的类型提示扩展到一些基本原生类型,如数组和对类名的硬编码类型。对于其他类型,您必须在方法中放入大量样板代码,以确保当您期望一个浮点数时,您得到一个(或使用hhvm ;-))。这个库解决了某些基本PHP类型和一些扩展类型的问题,这些扩展类型可以被认为是“缺少”的类型。

这个库最常见的使用场景是作为您公共方法的强类型后端。

    
    public function myFunc(StringType $str, IntType $ival);
    

Bingo:您的函数期望一个StringType和一个IntType,没有其他任何类型!

在此上下文中,强类型的主要目的是 保护您的公共方法不受不必要的副作用的影响。在使用的点展开原生类型。

次要用途是在您想要开始使用一些PHP中缺少的类型时,尤其是有理数(分数)和复数字类型。我基于这个库中的数字类型建立了一个相当全面的数学矩阵库。

PHP 7警告

PHP 7引入了对原生类型的类型提示,但问题是您将得到自动转换或类型转换。这不是我所期望的。在此期间,请使用此StrongType库来加强您的应用程序。

也就是说,一旦你掌握了基本类型的用法,你会发现它们非常适合传递和使用,可以与PHP原生类型互换使用,主要是因为它们支持__toString()方法和__invoke(),这些方法代理到get()方法。

    
    public function myFunc(StringType $str, IntType $ival)
    {
        echo $str;
        $foo = "The amount is {$ival}";
        $n = 2 * $ival();
    }
    

当前库涵盖了基本数据类型和一些扩展。

如果你想要更多,要么提出建议,要么更好的是,分叉它并提供一个拉取请求。

查看The Matrix Packages以获取Chippyash的其他包

如何

编码基础

非常简单的方法

这就是我们在日常工作中如何使用它来确保我们对某些函数的调用是一致的

function foo(FloatType $foo) {...}
$myFoo = foo(new FloatType(1);

注意。整数1将被转换为浮点数1.0,但这没关系,因为我们的方法foo()期望一个FloatType,并且使用PHP当前的类型提示可以强制执行它。

对于那些有毅力的人

通过Type Factory创建一个类型

    use Chippyash\Type\TypeFactory;
    $str = TypeFactory::create('string','foo');
    //or
    $str = TypeFactory::createString('foo');

    $int = TypeFactory::createInt(2);
    //or
    $int = Typefactory::create('int', 2);

    //some types can take two parameters
    $rat = TypeFactory::create('rational', 2, 3);

等等

支持的类型标签包括

  • bool(或boolean)
  • digit
  • float(或double)
  • complex
  • int(或integer)
  • natural
  • whole
  • rational
  • string

直接创建一个

    use Chippyash\Type\Number\Complex\ComplexType;
    use Chippyash\Type\Number\Rational\Rationaltype;
    use Chippyash\Type\String\DigitType;
    use Chippyash\Type\String\StringType;
    use Chippyash\Type\Number\FloatType;
    use Chippyash\Type\Number\IntType;
    $c = new ComplexType(new RationalType(new IntType(-2), new IntType(1)), new RationalType(new IntType(3), new IntType(4));
    $d = new DigitType(34);
    $s = new StringType('foo');
    $d2 = new DigitType('34foo'); // == '34'
    $r = new RationalType(new IntType(1), new IntType(2));

等等

通过Complex Type Factory创建一个复杂类型(注意,Type Factory使用这个工厂)

    use Chippyash\Type\Number\Complex\ComplexTypeFactory;
    $c = ComplexTypeFactory::create('13-2.67i');
    //same as
    $c = ComplexTypeFactory::fromString('13-2.67i');

    $c = ComplexTypeFactory::create(2.4, new IntType(-6));
    $c = ComplexTypeFactory::create(2, -61.78);
    $c = ComplexTypeFactory::create(new FloatType(2), -61.78);
    //i.e. any pair of numeric, intType, FloatType or RationalType values can be used to create
    //a complex type via the factory

通过Rational Type Factory创建一个有理类型(注意,Type Factory使用这个工厂,但直接使用它可能在某些情况下提供更细粒度的控制。)

    use Chippyash\Type\Number\Rational\RationalTypeFactory;
    $r = RationalTypeFactory::create(M_1_PI);    //results in 25510582/80143857
    $r = RationalTypeFactory::fromFloat(M_1_PI); //ditto
    $r = RationalTypeFactory::fromFloat(M_1_PI, 1e-5); //results in 113/355
    $r = RationalTypeFactory::fromFloat(M_1_PI, 1e-17);  //results in 78256779/245850922

    $r = RationalTypeFactory::create('2/3');
    //same as
    $r = RationalTypeFactory::fromString('2/3');

RationalTypeFactory::fromFloat遵循RationalTypeFactory::$defaultTolerance的当前设置。默认值是1e-15。你可以在程序开始时调用RationalTypeFactory::setDefaultFromFloatTolerance()来更改此值。

所有类型都支持TypeInterface

  • get() - 如果可能,以PHP原生类型返回值
  • set($value) - 设置值
  • __toString() - 魔术toString方法。以字符串形式返回值
  • __invoke() - 代理到get(),允许你编写$c()而不是$c->get()

数值类型,即IntType、WholeIntType、NaturalIntType、FloatType、RationalType和ComplexType支持NumericTypeInterface,它定义了以下方法

  • negate():对数字取反 - 注意,取反将为WholeInt和NaturalInt类型抛出\BadMethodCallException,因为它们不能是负数
  • asComplex():返回数字的复数实数表示(例如,2+0i)。对于复数类型,只需克隆现有对象。
  • asRational():返回数字的有理数表示。对于有理数类型,只需克隆现有对象。
  • asIntType():返回作为IntType的数字。对于IntType,只需克隆现有对象。
  • asFloatType():返回作为FloatType的数字。对于FloatType,只需克隆现有对象。
  • abs():返回数字的绝对值
  • sign():返回数字的符号:-1 == 负,0 == 零,1 == 正

IntType支持两个额外的方法

  • factors():数组:返回数字的因子数组
  • primeFactors():数组:返回[primeFactor => exponent,...],即primeFactor => 出现次数

此外,RationalType支持RationalTypeInterface

  • numerator() - 返回整数值分子
  • denominator() - 返回整数值分母

注意,AbstractRationalType修改了set()方法,将其代理到setFromTypes(),即调用RationalType::set()需要与setFromTypes()相同的参数

此外,ComplexType支持ComplexTypeInterface

  • r() - 返回作为RationalType的实部
  • i() - 返回作为RationalType的虚部
  • isZero() - 这个数字等于零吗?
  • isReal() - 这个数字是实数吗?即它是否为形式n+0i
  • isGuassian() - 判断这个数是否为高斯数,即 r 和 i 都等于整数
  • conjugate() - 返回这个数的共轭
  • modulus() - 返回模数,也称为这个数的绝对值或大小
  • theta() - 返回该数以极坐标表示时的角度(有时称为辐角)
  • radius() - 返回该数以极坐标表示时的半径(有时称为 Rho)
  • asPolar() - 返回以极坐标形式表示的复数,即数组 [半径, 角度]
  • polarQuadrant() - 返回复数的极坐标象限
  • polarString() - 以极坐标形式返回复数的字符串表示,即 r(cosθ + i⋅sinθ)

注意,ComplexType 修改了 set() 方法以代理到 SetFromTypes,即调用 ComplexType::set() 需要与 setFromTypes() 相同的参数。

PHP 没有ComplexType的原生等效,因此 get() 方法代理到 __toString() 方法并返回形式为 [-]a(+|-)bi 的内容,例如 '-2+3.6i',除非 ComplexType->isReal(),在这种情况下 get() 将返回一个浮点数或整数。如果您需要区分,请使用 ComplexType::toFloat(),如果该数不是实数,它将抛出异常。

ComplexType 的极坐标方法以及 ComplexTypeFactory::fromPolar(RationalType $radius, RationalType $theta) 方法支持极坐标复数。

仅从 V2 版本开始支持 GMP 扩展

库会自动识别 gmp 扩展的可用性,并将其用于 int、有理数和复数类型。

WholeIntType、NaturalIntType 或 FloatType 没有gmp支持。

  • 通过 TypeFactory 创建 WholeIntType 和 NaturalIntType 将返回 GMPIntType。
    • 对整数和自然数的验证被忽略 - 它们被视为整数
  • 通过 TypeFactory 创建 FloatType 将返回 GMPRationalType。

您可以通过调用以下代码在代码开始时强制库使用 PHP 原生类型

    use Chippyash\Type\RequiredType; 
    RequiredType::getInstance()->set(RequiredType::TYPE_NATIVE);

这将转而调用其他工厂的 setNumberType 方法,因此您不需要这样做

如果您想获取一个数字的 gmp 类型值,可以调用它的 gmp() 方法。

    //assuming we are running under gmp
    $i = TypeFactory::create('int', 2); //returns GMPIntType
    $i = TypeFactory::create('whole', -1); //returns GMPIntType
    $i = TypeFactory::create('natural', 0); //returns GMPIntType
    $gmp = $i->gmp(); //returns resource or GMP object depending on PHP version

    $r = TypeFactory::create('rational', 2, 3); //returns GMPRationalType
    $r = TypeFactory::create('float', 2/3); //returns GMPRationalType
    $gmp = $i->gmp(); //returns resource or GMP object depending on PHP version

    $r = TypeFactory::create('rational', 2, 3); //returns GMPRationalType
    $gmp = $r->gmp(); //returns array of gmp types, [numerator, denominator]

    $c = TypeFactory::create('complex', '2+3i'); //returns GMPComplexType
    $gmp = $c->gmp(); //returns array of gmp types, [[num,den],[num,den]] i.e. [r,i]

所有 GMP 类型都支持 GMPInterface,因此除了有 gmp() 方法外,它们还将有

  • public function asGMPIntType() 返回作为 GMPIntType 的数字。对于有理数类型,将返回 floor(n/d)
  • public function asGMPComplex() : 返回作为 GMPComplex 数字的数字,即 n+0i
  • public function asGMPRational(): 返回作为 GMPRational 数字的数字。

如果您使用类型工厂,将大大简化跟踪您实际实例化的类型,因为它们知道要创建哪些类型。因此,如果您希望您的代码既可以作为 PHP 原生也可以作为 GMP 运行,请使用工厂来创建您的数字类型。

更多文档

您可以在这里找到 API 文档

在文档目录中的Test Contract

查看ZF4 包以获取更多包

UML

class diagram

修改库

  1. 将其分支
  2. 编写测试
  3. 修改它
  4. 发起 pull request

发现了一个无法解决的错误吗?

  1. 将其分支
  2. 编写测试
  3. 发起 pull request

注意。在发起 pull request 之前,请确保您已经将分支重新基座到 HEAD

或者 - 提交一个问题票据。

在哪里?

库托管在Github上。它在Packagist.org上可用

安装

安装Composer

对于生产环境

除非有充分的理由不这样做,否则请使用V5版本。

    "chippyash/strong-type": ">=5.0.0,<6"

V5分支是默认分支,不会对早期版本进行进一步开发。

关于开发

克隆此仓库,然后在本地仓库根目录中运行Composer以拉取依赖项。

    git clone git@github.com:chippyash/Strong-Type.git StrongType
    cd StrongType
    composer update

要运行测试

    cd StrongType
    vendor/bin/phpunit -c test/phpunit.xml test/

许可证

本软件库在BSD 3条款许可证下发布(点击查看)

本软件库版权所有(c)2014-2018,Ashley Kitson,英国

本软件库包含的代码项是

  • 版权所有(c)2005-2014 Zend Technologies USA Inc. (点击查看
  • 在新的BSD许可证下发布

特别是以下代码项是

  • Chippyash\Type\String\DigitType的元素
  • Chippyash\Zend\ErrorHandler的所有内容

据我所知,所有包含的代码项都不会违反覆盖的许可证,反之亦然。因此,只要您坚持BSD许可证(或兼容性),那么您就是安全的。如果您有任何疑问,请寻求适当的建议。

如果包含代码项的原始版权所有者反对这种包含,请联系作者。

此库由JetBrains支持,他们为开源开发者提供IDE。

历史

V0... 预发布版

V1.0.0 原始发布

V1.0.1 移除对zendfilter包的要求,以减少依赖项大小

   Add NumericTypeInterface to support other usages of library

V1.0.2 为复杂数类型添加共轭方法

   rebase wholeInt and naturalInt type on intType

V1.0.3 为复杂数类型添加模方法

V1.0.4 修复RationalTypefactory::fromFloat无法识别零的问题

V1.0.5 为数值类型添加negate()方法

V1.0.6 为复杂数添加isReal()方法

    add toFloat() method for complex numbers if number isReal()

V1.0.7 为数值类型添加toComplex()方法

V1.0.8 为数值类型添加abs()方法

V1.0.9 为数值类型添加asRational、asFloatType和asIntType方法。将toComplex重命名为asComplex方法

V1.0.10 将Typefactory重构为使用as...方法

V1.0.11 确保as...方法中类型部分的隔离

V1.1.0 添加极坐标复数支持

    move interfaces to separate folder

V1.1.1 从fromFloat中移除硬编码的容差级别。使用默认的1e-15。

V1.1.2 确保克隆正确克隆内部对象

V1.1.3 重构以支持GMP类型

V2.0.0 添加GMP支持

V2.0.1 添加额外的gmp类型检查

V2.0.2 更新Zend依赖项

V2.0.3 如果未安装GMP则修复测试中断 - 将正确跳过

V2.0.4 将主页添加到composer.json定义中

V2.0.5 对计算器的复数创建问题进行小修

V2.0.6 将phpunit更新到~V4.3.0

V2.0.7 添加测试合约

V2.0.8 当启用GMP支持时

  • 通过 TypeFactory 创建 WholeIntType 和 NaturalIntType 将返回 GMPIntType。
  • 通过 TypeFactory 创建 FloatType 将返回 GMPRationalType。
  • 通过TypeFactory创建RationalType将返回GMPRationalType。
  • 通过TypeFactory创建ComplexType将返回GMPComplexType。

V2.0.9 修复合并

V2.1.0 将库降级以支持PHP5.3 - 仍有很多人在使用它!

V2.1.1 修复PHP5.3单元测试

V2.1.2 删除对Zend\StdLib的依赖

V2.1.3 优化代码整洁性

弃用Typefactory::setNumberType()方法

V3.0.0 BC中断:将命名空间从chippyash\Type重命名为Chippyash\Type

V3.0.1 添加链接到包

V3.0.2 验证PHP7兼容性

V4.0.0 BC中断:结束PHP5.3支持。构建脚本更改

V4.0.1 更新composer - 由于packagist composer.json格式更改而强制

V5.0.0 BC中断:结束对PHP <5.6的支持

V5.1.0 许可证从GPL V3更改为BSD 3条款