| : | Javascript | : | PHP Index | : | MySQL | : |
| : | Source | : | : | Explanation | : | : | Example | : | : | Todo | : | : | Feedback | : |
Checks whether a string is a valid ISBN (International Standard Book Number) number
Added: 2009-05-10 23:54:34
Last update: 2009-06-18 23:54:34
<?
/**
* @copyright Copyright (c) 2009 Martijn Korse (http://devshed.excudo.net)
* @license New BSD License
*/
/**
* This function checks whether the given string is a valid isbn number
*
* @param string $isbn The number that we want to check.
* This can be a 10 digit or 13 digit string
*
* @return boolean
*/
function checkIsbn($isbn)
{
// going to perform isbn-10 check
if (strlen($isbn) == 10)
{
$subTotal = 0;
$mpBase = 10;
for ($x=0; $x<=8; $x++)
{
$mp = $mpBase - $x;
$subTotal += ($mp * $isbn{$x});
}
$rest = $subTotal % 11;
$checkDigit = $isbn{9};
if (strtolower($checkDigit) == "x")
$checkDigit = 10;
return $checkDigit == (11 - $rest);
}
// going to perform isbn-13 check
elseif (strlen($isbn) == 13)
{
$subTotal = 0;
for ($x=0; $x<=11; $x++)
{
$mp = ($x + 1) % 2 == 0 ? 3 : 1;
$subTotal += $mp * $isbn{$x};
}
$rest = $subTotal % 10;
$checkDigit = $isbn{12};
if (strtolower($checkDigit) == "x")
$checkDigit = 10;
return $checkDigit == (10 - $rest);
}
else
{
return False;
}
}
# The following class does the same as the function above, except that it can be used as a Zend_Validator;
# for those of you who are using the Zend Framework
# I would recommend using it if you can, since the it gives more feedback about what is wrong with the input
# than the function above
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2009 Martijn Korse (http://devshed.excudo.net)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Excudo_Validate_Isbn extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains non-numerical values
*/
const CONTAINS_NON_DIGITS = 'containsNonDigits';
/**
* Validation failure message key for when the value has a length that is not defined in $_validLengths
*/
const INVALID_LENGTH = 'lengthInvalid';
/**
* Validation failure message key for when the value has a length that does not match the length set by setLength()
*/
const INVALID_REQUIRED_LENGTH = 'requiredLengthInvalid';
/**
* Validation failure message key for when the value is not a valid isbn number
*/
const INVALID_ISBN = 'isbnInvalid';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::CONTAINS_NON_DIGITS => "'%value%' contains non-numerical values other then X",
self::INVALID_LENGTH => "'%value%' does not appear to have a valid length",
self::INVALID_REQUIRED_LENGTH => "'%value%' does not have the required isbn length",
self::INVALID_ISBN => "'%value%' is not a valid isbn number"
);
/**
* A valid isbn number either contains exactly 10 or 13 numbers
* So, we mark these as valid lengths
*
* @var array
*/
private $_validLengths = array(
10,
13
);
/**
* You can demand that the isbn has one of the valid lengths by giving that value to this variable,
* using it's setter or by passing it to the constructor
*
* @see setLength()
*
* @var integer
*/
protected $_length;
/**
* Sets validator options
*
* @param integer $length OPTIONAL
*
* @return Excudo_Validate_ISBN
*/
public function __construct($length = null)
{
$this->setLength($length);
}
/**
* Returns the length and isbn number should have
*
* @return integer
*/
public function getLength()
{
return $this->_length;
}
/**
* Sets the length an isbn number should have
*
* @return void
*/
public function setLength($length)
{
if (!is_null($length) && !in_array((int) $length, $this->_validLengths))
{
}
elseif (!is_null($length))
{
$this->_length = (int) $length;
}
else
{
$this->_length = $length;
}
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if $value is a valid ISBN number
* If optional $length is set we also check if the length of the ISBN number is correct
* which means that it has to consist of either 10 or 13 digits.
*
* @param string $value
*
* @return boolean
*/
public function isValid($isbn)
{
$this->_setValue($isbn);
if (preg_match("/[^0-9x]/", $isbn))
{
$this->_error(self::CONTAINS_NON_DIGITS);
return false;
}
elseif (!in_array(strlen($isbn), $this->_validLengths))
{
$this->_error(self::INVALID_LENGTH);
return false;
}
elseif (!is_null($this->_length) && strlen($isbn) != $this->_length)
{
$this->_error(self::INVALID_REQUIRED_LENGTH);
return false;
}
// going to perform isbn-10 check
if (strlen($isbn) == 10)
{
$subTotal = 0;
$mpBase = 10;
for ($x=0; $x<=8; $x++)
{
$mp = $mpBase - $x;
$subTotal += ($mp * $isbn{$x});
}
$rest = $subTotal % 11;
$checkDigit = $isbn{9};
if (strtolower($checkDigit) == "x")
$checkDigit = 10;
$result = $checkDigit == (11 - $rest);
if($result === false)
{
$this->_error(self::INVALID_ISBN);
return false;
}
else
{
return true;
}
}
// going to perform isbn-13 check
elseif (strlen($isbn) == 13)
{
$subTotal = 0;
for ($x=0; $x<=11; $x++)
{
$mp = ($x + 1) % 2 == 0 ? 3 : 1;
$subTotal += $mp * $isbn{$x};
}
$rest = $subTotal % 10;
$checkDigit = $isbn{12};
if (strtolower($checkDigit) == "x")
$checkDigit = 10;
$result = $checkDigit == (10 - $rest);
if($result === false)
{
$this->_error(self::INVALID_ISBN);
return false;
}
else
{
return true;
}
}
else
{
throw new Exception('This situation should never happen. It probably did happen because the validLength variable has been modified and the internal isValid method hasn\'t been altered accordingly');
}
}
}