-
-
Notifications
You must be signed in to change notification settings - Fork 110
Closed
Description
- 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;
}Metadata
Metadata
Assignees
Labels
No labels