- bug report? yes
- feature request? no
- version: 2.4.5
Description
The use of the function isset return false. We used it to check relation over sevetal tables. This examle is for easy for ease of understanding simplified.
$row = $context->table('book')->get(2);
if (isset($row->author->name)) { ... }
This condition returns false under php 7.0 and 7.1. In php 5.6 it returns the expected value true. Call var_dump($row->author->name) will write the correct author name under all php versions.
Steps To Reproduce
I prepare test:
<?php
/**
* @dataProvider? ../databases.ini
*/
use Tester\Assert;
require __DIR__ . '/../../connect.inc.php'; // create $connection
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/../../files/{$driverName}-nette_test1.sql");
test(function () use ($context) {
$row = $context->table('book')->get(2);
Assert::same('Jakub Vrana', $row->author->name);
Assert::true(isset($row->author->name));
});
On php 5.6 is corrent. On php 7 or greate break with fail. The difference is how php internally interprets the isset function.
Testing example:
<?php
class Foo
{
private $bar;
public function __construct()
{
unset($this->bar);
}
public function __isset($name)
{
var_dump(__METHOD__ . '('. $name .')');
return true;
}
public function __get($name)
{
var_dump(__METHOD__ .'('. $name .')');
return $this;
}
}
$instance = new Foo();
var_dump(isset($instance->rel1->rel2->property));
In php 5.6 returns the result:
php test.php
string(19) "Foo::__get(surname)"
string(16) "Foo::__get(name)"
string(17) "Foo::__isset(foo)"
bool(true)
and in php 7.0 or great returns:
php test.php
string(18) "Foo::__isset(rel1)"
string(16) "Foo::__get(rel1)"
string(18) "Foo::__isset(rel2)"
string(16) "Foo::__get(rel2)"
string(22) "Foo::__isset(property)"
bool(true)
The solution is add to function __isset check the existence of the relation:
public function __isset($key)
{
if ($this->accessColumn($key)) {
return isset($this->data[$key]);
}
$referenced = $this->table->getReferencedTable($this, $key);
if ($referenced !== false) {
$this->accessColumn($key, false);
return true;
}
$this->removeAccessColumn($key);
return false;
}
Description
The use of the function
issetreturn false. We used it to check relation over sevetal tables. This examle is for easy for ease of understanding simplified.This condition returns
falseunder php 7.0 and 7.1. In php 5.6 it returns the expected valuetrue. Callvar_dump($row->author->name)will write the correct author name under all php versions.Steps To Reproduce
I prepare test:
On php 5.6 is corrent. On php 7 or greate break with
fail. The difference is how php internally interprets theissetfunction.Testing example:
In php 5.6 returns the result:
and in php 7.0 or great returns:
The solution is add to function
__issetcheck the existence of the relation: