I have a method which accepts a PDO object as an argument, to allow the user to use an existing connection rather then the method to open a new one, and save resources:
public static function databaseConnect($pdo = null) {
I am aware of is_object()
to check if the argument is an object, but I want to check if $pdo
is a PDO object, and not just an object.
Because the user can easily enter (by mistake?) a different kind of object, a mysqli or such, and the entire script will break apart.
In short: How can I check a variable for a specific type of object?
You can use instanceof
:
if ($pdo instanceof PDO) {
// it's PDO
}
Be aware though, you can't negate like !instanceof
, so you'd instead do:
if (!($pdo instanceof PDO)) {
// it's not PDO
}
Also, looking over your question, you can use object type-hinting, which helps enforce requirements, as well as simplify your check logic:
function connect(PDO $pdo = null)
{
if (null !== $pdo) {
// it's PDO since it can only be
// NULL or a PDO object (or a sub-type of PDO)
}
}
connect(new SomeClass()); // fatal error, if SomeClass doesn't extend PDO
Typed arguments can be required or optional:
// required, only PDO (and sub-types) are valid
function connect(PDO $pdo) { }
// optional, only PDO (and sub-types) and
// NULL (can be omitted) are valid
function connect(PDO $pdo = null) { }
Untyped arguments allow for flexibility through explicit conditions:
// accepts any argument, checks for PDO in body
function connect($pdo)
{
if ($pdo instanceof PDO) {
// ...
}
}
// accepts any argument, checks for non-PDO in body
function connect($pdo)
{
if (!($pdo instanceof PDO)) {
// ...
}
}
// accepts any argument, checks for method existance
function connect($pdo)
{
if (method_exists($pdo, 'query')) {
// ...
}
}
As for the latter (using method_exists
), I'm a bit mixed in my opinion. People coming from Ruby would find it familiar to respond_to?
, for better or for worse. I'd personally write an interface and perform a normal type-hint against that:
interface QueryableInterface
{
function query();
}
class MyPDO extends PDO implements QueryableInterface { }
function connect(QueryableInterface $queryable) { }
However, that's not always feasible; in this example, PDO
objects are not valid parameters as the base type doesn't implement QueryableInterface
.
It's also worth mentioning that values have types, not variables, in PHP. This is important because null
will fail an instanceof
check.
$object = new Object();
$object = null;
if ($object instanceof Object) {
// never run because $object is simply null
}
The value loses it's type when it becomes null
, a lack of type.