When working with relationships via alias inside a loop, I get a segmentation fault error.
I have two models (simplified example):
class Person
{
public $id;
public $company_id;
public $address_id;
public function initialize()
{
$this->hasOne('address_id', Address::class, 'id', [
'alias' => 'Address'
]);
}
public static function fetchByCompanyId(int $companyId): array
{
$builder = DI::getDefault()->getModelsManager()->createBuilder()
->columns(['person.*, address.*'])
->from(['person' => Person::class])
->leftJoin(Address::class, 'person.address_id = address.id', 'address')
->where('person.company_id = :companyId:');
$resultSet = $builder->getQuery()->execute(['companyId' => $companyId]);
$persons = [];
foreach ($resultSet as $row) {
$person = $row['person'];
$address = $row['address'];
$person->Address = $address->id === null ? null : $address;
$persons[] = $person;
}
return $persons;
}
}
class Address
{
public $id;
}
Here is a sample function that produces segmentation fault:
class DebugController extends Controller
{
public function index(): string
{
$companyIds = [1, 2];
foreach ($companyIds as $companyId) {
$persons = Person::fetchByCompanyId($companyId);
foreach ($persons as $person) {
echo $person->id . " + " . $person->Address->id;
}
}
return 'OK';
}
}
If I remove an element from $companyIds
and leave only one (so foreach loops once), function works without an error. However, if there are multiple loops, it throws a segmentation fault error when called:
[core:notice] [pid 1] AH00052: child pid 27 exit signal Segmentation fault (11)
My questions are:
- I am setting the relationship manually like so
$person->Address = $address->id === null ? null : $address;
because I don't want to make an additional DB call to fetch the relationship. Is this the correct way to do this or is there another way? - If 1) is correct, what causes segmentation fault?
- Is this a bug or am I doing something I should't be doing?
Possibly worth mentioning:
If I add this call after each Person::fetchByCompanyId
, it works fine in all cases:
$this->modelsManager->__destruct();
However, I don't like this solution since it doesn't reuse modelsManager, but destroys and creates a new one on each loop.
Also, if I'd do a basic Person:find()
+ $person->Address
, everything would work, but it would make a new DB query for each alias call and I don't want that.
Any help/insight is appreciated, thanks!
Additional info:
PHP 7.4
Phalcon 4.0.5
Running inside a docker