National Insurance Number Validation I'm a beginner to PHP and I've written a function that validates a U.K National Insurance Number. The function works by checking whether the given number against the format below;


  The National Insurance Number ($NINO) is made up of 3 components in the
  format AAnnnnnnA. The 3 components are the prefix, numeric body and
  suffix.
  
  Prefix
  
  The first two alpha characters, validated as follows:
  
  • The prefix must not be BG, GB, NK, KN, TN, NT or ZZ
  
  • The prefix must not contain D F I Q U or V
  
  • The second character of the NINo prefix must not be O
  
  Numeric body
  
  The 8 numeric characters of the NINO, validated as follows:
  
  • Must be numeric in the range 000000 – 999999
  
  Suffix
  
  The final alpha character; validated as follows:
  
  • Must be in the range A – D 


&lt;?php

function validateNI($NINO) {
    $NILength = strlen($NINO);

    if (!($NILength &lt; 10 | $NILength &gt; 10)) {
        $NIParts = str_split($NINO, 2);

        if(!(preg_match("/[^!@#$%^&amp;*]*(BG|GB|NK|TN|NT|ZZ|D|F|I|Q|U|V)[^!@#$%^&amp;*]*/i", $NIParts[0]))) {

            $NIPartsSplit = str_split($NIParts[0]);

            if(preg_match("/[^!@#$%^&amp;*]*(O)[^!@#$%^&amp;*]*/i", $NIPartsSplit[1])) {
                echo "Invalid National Insurance Number.";
            } else {
                $NIPartsNum = $NIParts[1].$NIParts[2].$NIParts[3];

                if (is_numeric($NIPartsNum)) {

                    if(preg_match("/[^!@#$%^&amp;*]*(A|B|C|D)[^!@#$%^&amp;*]*/i", $NIParts[4])) {
                        echo "Valid National Insurance Number.";
                    } else {
                        echo "Invalid National Insurance Number.";
                    }
                } else {
                    echo "Invalid National Insurance Number.";
                }
            }

        } else {
            echo "Invalid National Insurance Number.";
        }

    } else {
        echo "Invalid National Insurance Number.";
    }
}

validateNI("AA1220091A");

?&gt;


I'm looking for advice on how I can reduce the overall lines of code (including the use of regex) as well as increasing the efficiency and simplicity of my code.
I am happy for you, that you are asking for help with refactoring this scary function.
First of all, you must not write more than 2 indentations with if statements, if you want to be a great developer.

Secondly, when you write a program, keep in your mind that every method or function must do one simple task.

Well, what is the responsibility of your function?


check insurance number Length.
check prefix.
check the second string of prefix.
check suffix.
check the numeric body number.


Perfect, why must we create a class instead of keeping your method?

There is one principle, it is KISS(Keep it simple stupid),
the main idea behind this principle is to keep your methods or classes as simple and stupid as possible.

For that, we should create new methods for our responsibilities above. For example to check the first responsibility which is "check insurance number length" we will create a method called isNotValidInsuranceNumberLength to do that for us etc..

Since we have many methods, we should encapsulate all of them within a class, that will be its responsibility to take care of the national insurance number validation.

And this touches on the SRP(single responsibility principle) because we must ensure that our class will have one and only one reason to change(validation of the national insurance number).

I was changing the imbricated if statements by small methods that describe what they do exactly by its name.


  I advise you, that when you write code think like you are writing a
  story.
  
  another advice: read Uncle Bob clean code's book.


my refactorization is below : 

&lt;?php

class  NationalInsuranceNumberValidator
{
    $insuranceNumber = null;

    public function __construct($insuranceNumber)
    {
        $this-&gt;insuranceNumber = $insuranceNumber;
    }

    public function validate()
    {
        if($this-&gt;isNotValidInsuranceNumberLength())
        {
            echo "Invalid National Insurance Number. isNotValidInsurenceNumberLength";
        }
        elseif($this-&gt;prefixIsNotValid())
        {
            echo "Invalid National Insurance Number. prefixIsNotValid";
        }
        elseif($this-&gt;secondPartOfPefixIsNotValid())
        {
            echo "Invalid National Insurance Number. secondPartOfPefixIsNotValid";
        }
        elseif($this-&gt;suffixIsNotValid())
        {
            echo "Invalid National Insurance Number. suffixIsNotValid";
        }
        elseif($this-&gt;isNotNumericBody())
        {
            echo "Invalid National Insurance Number. isNotValidNumericBody";
        }
        else
        {
            echo "Valid National Insurance Number.";
        }
    }

    private function isNotValidInsuranceNumberLength()
    {
        $insuranceNumberLength = strlen($this-&gt;insuranceNumber);

        return $insuranceNumberLength &lt; 10 || $insuranceNumberLength &gt; 10;
    }

    private function prefixIsNotValid()
    {
        return preg_match("/[^!@#$%^&amp;*]*(BG|GB|NK|TN|NT|ZZ|D|F|I|Q|U|V)[^!@#$%^&amp;*]*/i", $this-&gt;getPrefix()) == 1 ? true : false;
    }

    private function secondPartOfPefixIsNotValid()
    {
        $prefix = $this-&gt;getPrefix();

        return preg_match("/[^!@#$%^&amp;*]*(O)[^!@#$%^&amp;*]*/i", $prefix[1]) == 1 ? true : false;
    }

    private function suffixIsNotValid()
    {
        return preg_match("/[^!@#$%^&amp;*]*(A|B|C|D)[^!@#$%^&amp;*]*/i", $this-&gt;getSuffix()) == 1 ? false : true;
    }

    private function isNotNumericBody()
    {
        return !is_numeric($this-&gt;getNumericBody());
    }

    private function getPrefix()
    {
        return substr($this-&gt;insuranceNumber, 0, 2);
    }

    private function getNumericBody()
    {
        return substr($this-&gt;insuranceNumber, 2, 7);
    }

    private function getSuffix()
    {
        return substr($this-&gt;insuranceNumber, 9, 1);
    }
}


$nationalInsuranceNumber = new NationalInsuranceNumberValidator('AA1220091C');

$nationalInsuranceNumber-&gt;validate();