English 中文(简体)
PHP ORM和优化关系查询
原标题:PHP ORMs and optimized relationship queries

I need a PHP ORM to work with relations well. Please consider code below in Zend:

$persons = new Persons();
$person = $persons->find(5)->current();
echo  Name:  .$person->fullname;

$phones = $person->findDependentRowset( Phones );
foreach($phones as $phone)
    echo  Phone:  .$phone->phonenumber; 

Or code below in xPDO:

$person = $xpdo->getObject( Persons , 5);
echo  Name:  .$person->get( fullname );

$phones = $person->getMany( Phones );
foreach($phones as $phone)
    echo  Phone:  .$phone->get( phonenumber );

in both scripts, ORMs executes two queries as below:

SELECT * FROM persons WHERE id=5;
SELECT * FROM phones WHERE person=5;

It means one query for main object and one query for each relation but what i need is using ONE query for main object and its relations! xPDO can do it as below:

$person = $xpdo->getObjectGraph( Persons ,  {"Phones":{}} , 5);
echo  Name:  .$person->get( fullname );

foreach($person->Phones as $phone)
    echo  Phone:  .$phone->get( phonenumber );

执行这一询问:

SELECT * FROM persons
LEFT JOIN phones ON phones.person=persons.id
WHERE persons.id=5

This is great but its not possible to set fields to get from tables! it means in this case xPDO use "SELECT * " so if i get an object and its 4 relations, i will get all fields of all these tables!

因此,如上所述,需要一个办公室来执行询问:

SELECT persons.fullname , phones.phonenumber FROM persons
LEFT JOIN phones ON phones.person=persons.id
WHERE persons.id=5

Doctrine can do it via DQL but i think Doctrine is not good for personal projects. Is there any PHP ORM to do this?

Thanks AHHP

最佳回答

xPDO can do it. You just have to adjust your thinking and your request.

Remember the objectGraph utilizes the class name of the object, where as the relationships in the graph are used in the graph and query.

 $criteria = $this->xpdo->newQuery( prefixClient );
            if (!empty($limit))
                $criteria->limit($limit);
            $criteria->where(array( Child.planid  => $this->getPrimaryKey(),
                                    Child.active  => true,
                                    GrandChild.someAttribute  => true,
                                    GreatGrandChild.someOtherAttribute  => true,
                                    suspended  => false
                             ));

            $out = $this->xpdo->getCollectionGraph( prefixClient ,  {"Child":{"GrandChild":{"GreatGrandChild":{}}}} , $criteria);

你在关系的任何方面,包括目前被中止=和无效的路线上显示的物体,确定了WHERE。

我的这本书可能有助于你建立你的计划和关系。 物体应永远为独角,而其关系可以是复方(1:M)或单体(1:1)。

问题回答

Oh Man,

我吃了约两个月的狗,我爱。 RED BEAN。

http://www.redbeanphp.com/“rel=“nofollow”http://www.redbeanphp.com/

Nested beans, which is their words for having one object as a property of another.

http://www.redbeanphp.com/manual/nested_bean

普通档案相对较少。 同LQ公司合作。 我正在利用该项目开展大规模项目,并热爱我能够迅速做事。

John.

http://gacelaphp.com

1) Inheritance relationship

例如:

CREATE TABLE wizards (
    wizardId INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    fname VARCHAR(255) NOT NULL,
    lname VARCHAR(255) NOT NULL,
    ROLE ENUM( teacher ,  student ) NULL,
    addressId INT UNSIGNED NULL,
    CONSTRAINT fk_address_wizard
    FOREIGN KEY (addressId)
    REFERENCES addresses(addressId)
    ON DELETE SET NULL
) ENGINE = Innodb;

CREATE TABLE students (
    wizardId INT UNSIGNED NOT NULL PRIMARY KEY,
    houseId INT UNSIGNED NOT NULL,
    isDAMembmer BOOL NOT NULL DEFAULT 0,
    CONSTRAINT fk_wizard_student
    FOREIGN KEY (wizardId)
    REFERENCES wizards(wizardId)
    ON DELETE CASCADE,
    CONSTRAINT fk_house_students
    FOREIGN KEY (houseId)
    REFERENCES houses(houseId)
    ON DELETE RESTRICT
) ENGINE = Innodb;

The students table has the same primary key as the wizards table and because of the foreign key relationship definition, Gacela will detect that students inherits all of the fields from wizards.

2) Dependent relationship

这可能更接近你重新寻找:

CREATE TABLE addresses (
    addressId INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    locationName VARCHAR(255) NOT NULL
) ENGINE = Innodb;

CREATE TABLE wizards (
    wizardId INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    fname VARCHAR(255) NOT NULL,
    lname VARCHAR(255) NOT NULL,
    ROLE ENUM( teacher ,  student ) NULL,
    addressId INT UNSIGNED NULL,
    CONSTRAINT fk_address_wizard
        FOREIGN KEY (addressId)
        REFERENCES addresses(addressId)
        ON DELETE SET NULL
) ENGINE = Innodb;

However, this example still differs slightly from your example because the addressId is in the wizards table thus creating a belongsTo relationship rather than a hasMany which is what your example reflects.

There is a third option available in Gacela, however I would first suggest that you consider that while it is often preferable to fetch data eagerly, there are real performance implications in always fetching eagerly rather than lazy loading data. It is for this reason that Gacela (and basically every other Data Mapper or ORM) by default does not eagerly fetch data from hasMany relationships. That said, you could write something like the following:

class Mapper extends GacelaMapper 
{

    public function find($id)
    {
        $query = $this->_source()->query();

        $query->from( persons , array( fullName ))
            ->join( phones ,  phones.person=persons.id , array( phonenumber ),  left )
            ->where( persons.id = :id , array( :id  => $id);

        $data = $this->_source->query($query);

        return $this->_load($data);
    }
}




相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签