Defining Terms - axiom82/PHP-Contract GitHub Wiki

Creating terms is the easy part. And so is understanding the available definitions, and applying those definitions to terms in order to compliment your Contracts.

Full List of Contract Term Definition Types

Here is a list of definitions available to Contract Terms:

  • allowed: The term may contain only the specified fields
  • alone: The term must be alone, having no siblings
  • alpha: The term must be an alphabetical string
  • alphaNumeric: The term must be an alplanumeric string
  • alphaDash: The term must be an alphanumeric allowing dashes
  • alphaUnderscore: The term must be an alphanumeric allowing unscores
  • arraylist: The term must be an array
  • base64: The term must be a base64 string
  • between: The term must be between the range of the two values
  • boolean: The term must be a boolean
  • count: The term must be the count of the value (for arrays)
  • decimal: The term must be a decimal
  • earlier: The term must be earlier than the value
  • email: The term must be an email address
  • equals: The term must match the value
  • greaterThan: The term must be greater than the value
  • id: The term must be an id (a natural positive number)
  • in: The term must be in the values of the array
  • integer: The term must be an integer
  • ip: The term must be an ip address
  • later: The term must be later than the value
  • length: The term must be the length of the value
  • lessThan: The term must be less than the value
  • many: The term must be an array with more than one element
  • natural: The term must be a natural number
  • naturalPositive: The term must be a natural positive number
  • none: The term must be an empty value or values
  • not: The term must not be equal to the value or values
  • null: The term must be null
  • numeric: The term must be numeric
  • object: The term must be an object that is an instance of the value
  • one: The term must be an array with one and only one element
  • optional: The term is not required
  • phone: The term must be a phone number
  • required: The term must be non-empty or must be an array with the specific fields
  • string: The term must be a string
  • url: The term must be URL
  • withData: The term, after the contract filters out invalid data, must have one or more valid values

Defining Terms

The following basic examples demonstrate the power of PHP-Contract.

Example: Defining Terms for Adding Numbers

<?php

public function addNumbers($number1, $number2, $number3 = null){
		
    $contract = new Contract();
    $contract->term('number1')->integer();
    $contract->term('number2')->integer();
    $contract->term('number3')->optional();
    $contract->term('number3')->integer();
    $contract->metOrThrow();

    $sum = $number1 + $number2; if ($number3) $sum += $number3;
    return $sum;

}

?>

The above code is a simple function for adding two or three numbers together. The Contract verifies the types of the arguments passed through the function. In this case, that all three are integers, allowing that the third number is an optional argument. By defining the third term as optional, the Contract will only verify the term’s definitions if a value is indeed present. If the value is null or empty, it is therefore optional and considered verified. If the optional term has a value, it must meet all of its definitions.

The purpose of PHP-Contract, in this case, is to provide argument type security. If the the addNumbers() function does not contain integer types, then the function will throw an exception of type Contract_Exception. If no exception is thrown, the sum of the numbers is calculated and returned as expected.

As you can see, PHP-Contract provides a formal way of ensuring the data types being passed through functions, class methods, and even procedural PHP syntax.

Using Short Form for Coding Contracts

The following code is functionality equivalent to that which is above, with the exception that it is syntactical structured in a different style, a “short-form” for writing the Contract code itself.

<?php

public function addNumbers($number1, $number2, $number3 = null){
		
    $contract = new Contract();
    $contract->term('number1')->integer()->end()
             ->term('number2')->integer()->end()
             ->term('number3')->optional()->integer()->end()
             ->metOrThrow();

    $sum = $number1 + $number2; if ($number3) $sum += $number3;
    return $sum;

}

?>

Coding Contracts On A Single Line

In the short-form example above, the Contract is using method chaining to define its terms. To fully optimize the space required for creating a Contract, we can employ Contract_Term::end(), which allows our code to define the Contract Terms on a single line:

<?php

public function addNumbers($number1, $number2, $number3 = null){
		
    new Contract()->term('number1')->integer()->end()->term('number2')->integer()->end()->term('number3')->optional()->integer()->end()->metOrThrow();

    $sum = $number1 + $number2; if ($number3) $sum += $number3;
    return $sum;

}

?>

Example: Defining Terms for Formatting Strings

<?php

public function formatBankStatement($memberName, $accountBalance, $statementDate){
		
    $contract = new Contract();
    $contract->term('memberName')->alpha();
    $contract->term('accountBalance')->decimal()->greaterThan(500.00);
    $contract->term('statementDate')->date()->later(strtotime('last month'));
    $contract->metOrThrow();

    return sprintf('Member %s has a balance of %d as of the date $s', $memberName, $accountBalance, $statementDate);

}

?>

The Contract above ensures that formatBankStatement() has an alphabetical string $memberName, a floating-point decimal $accountBalance, and a date later than last month’s date $statementDate. If the types and values for the arguments data is not met, an exception is thrown to alert the application that the function does not have what it needs to format a bank statement for this month. While these examples are simply to demonstrate the syntax of PHP-Contract, please continue reading the subsequent Wiki pages, as they demonstrate real-world usage examples.

Intermediate Contract Examples

Next, we will be talking about intermediate examples in using PHP-Contract, for use-cases like Defining Terms For Model Methods.

⚠️ **GitHub.com Fallback** ⚠️