PHP int类型被解释为float,break page

I'm learning OOP in PHP 7, following an example on a book. On the code

<?php 
    class Book {
        public $isbn;
        public $title;
        public $author;
        public $available;

        public function getPrintableTitle() : string {
            $result = '<i>'. $this -> title 
                    . '</i> - '. $this -> author;
            if (!$this->available) {
                $result .= ' <b>Not available</b>';
            }
            return $result;
        }

        public function getCopy(): bool{
            if ($this -> available < 1) {
                return false;
            } else {
                $this -> available--;
                return true;
            }
        }

        public function __construct(
            int $isbn, 
            string $title, 
            string $author, 
            int $available
        ) {
            $this -> isbn = $isbn;
            $this -> title = $title;
            $this -> author = $author;
            $this -> available = $available;
        }
    }

    $book = new Book(98765432123457, '1984', 'George Orwell', 12);

    if($book->getCopy()) {
        echo 'Here, your copy. <br />';
    } else {
        echo 'Sorry, no copies available for this book. <br />';
    }

    var_dump($book->isbn);
?>

I get an error that says:

Fatal error: Uncaught TypeError: Argument 1 passed to Book::__construct() must be of the type integer, float given, called in /home/jorge/Learning/php_sandbox/book.php on line 39 and defined in /home/jorge/Learning/php_sandbox/book.php:26 Stack trace: #0 /home/jorge/Learning/php_sandbox/book.php(39): Book->__construct(98765432123457, '1984', 'George Orwell', 12) #1 {main} thrown in /Learning/php_sandbox/book.php on line 26

Tried to search at php online docs, but couldn't find a reason to this error. It seems to me that php is interpreting the int 98765432123457 as a float because of the comma at the end of the statement. If so, is there a way to fix it?

Your ISBN, 98765432123457, is just slightly larger than what fits in an unsigned 32-bit integer. (log 98765432123457 == 32.22376878216809).

I suspect that as PHP parses your source code, it internalizes that string of digits as a float so as to represent a number larger than what can be encoded as a 32-bit int.

While ISBNs use only digits, I would not consider them to be numbers. (After all, the first few digits designate a country, some representations have dashes, and some representations have a leading 0.) I would represent this with a String instead.

larger integers convert to float so use float instead in the constructor

Based on your error, it is safe to assume you are using a 32 bit installation of PHP and therefore your ISBN is greater than PHP_MAX_INT which is between -2,147,483,648 to 2,147,483,647.

As per the documentation:

The largest integer supported in this build of PHP. Usually int(2147483647). Available since PHP 5.0.5

also from the documentation:

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18, except on Windows prior to PHP 7, where it was always 32 bit. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, maximum value using the constant PHP_INT_MAX since PHP 5.0.5, and minimum value using the constant PHP_INT_MIN since PHP 7.0.0.

Consider changing the ISBN parameter to a string.

Live Example

Repl - This is a 64 bit system hence the larger number but the error output is the same if it maximum integer value is exceeded.

In this case the ISBN does have some formatting business logic.

I would recommend a class called ISBN - that can parse a float or string, and then verify it's validity (however you want).

so -

<?php 
class ISBN {
    private $isbn;

    function __construct($value) {
        //business logic here to make sure the isbn value fits the logic
        //your system needs
        $this->isbn = $value;
   }

   function __get($value) {
       //Some logic here to gate the $value
       //or setup actual member functions as would be proper
       return $this-isbn;
   }
}

class Book {
    public $isbn;
    public $title;
    public $author;
    public $available;

    public function getPrintableTitle() : string {
        $result = '<i>'. $this -> title 
                . '</i> - '. $this -> author;
        if (!$this->available) {
            $result .= ' <b>Not available</b>';
        }
        return $result;
    }

    public function getCopy(): bool{
        if ($this -> available < 1) {
            return false;
        } else {
            $this -> available--;
            return true;
        }
    }

    public function __construct(
        string $isbn, 
        string $title, 
        string $author, 
        int $available
    ) {
        $this -> isbn = new ISBN($isbn);
        $this -> title = $title;
        $this -> author = $author;
        $this -> available = $available;
    }
}

$book = new Book(98765432123457, '1984', 'George Orwell', 12);

if($book->getCopy()) {
    echo 'Here, your copy. <br />';
} else {
    echo 'Sorry, no copies available for this book. <br />';
}

var_dump($book->isbn);
?>