2009-11-16 3 views
2

Я работаю на запрос, где я тянуть данные из нескольких таблиц с использованием левого присоединяется так:возвращаемый результат объекта из PHP дб запроса

 
$query = " 
    SELECT 
     users.name, 
     users.email, 
     address.street, 
     address.city, 
     address.state, 
     address.zip 
    FROM users  
LEFT JOIN(
     SELECT 
      addresses.street, 
      addresses.city, 
      addresses.state, 
      addresses.zip, 
      `addresses.user_id ` 
     FROM addresses 
) 
AS address 
ON users.id = `address.user_id` 
WHERE users.id = 1"; 

$mysql = new mysql(HOST, USER, PASS, DBNAME); 
$result = $mysql->query($query)->fetch_object(); 

Результаты, которые я получаю сейчас я могу получить доступ к результатам, как это:

 
    // get name 
    $result->name; 
    //get street address 
    $result->street; 

Поскольку запрос в конечном итоге станет чем-то более сложным, чем это. Я хотел бы быть в состоянии получить доступ к данным, как это:

 
// get user name 
$result->user->name; 

// get the street address 
$result->address->street; 

Это поможет сделать данные легче читать, так как некоторые из таблицы аналогичным образом с именем поля.

Любая помощь будет большой благодарностью.


EDIT: (в ответ на Стив)

Я знаком с ORMs, и я в настоящее время с помощью платформы Kohana. Я заинтересован в сокращении фактического количества запущенных запросов. ORM в структуре Kohana вызывает «SELECT *» для каждой таблицы/модели, которую вы вызываете. Я бы предпочел не делать этого, если мне это не нужно.

Выполнение двух отдельных запросов (как показано в примере) не так уж и важно, но в моем реальном примере я буду извлекать данные из примерно 10 отдельных таблиц, поэтому я бы предпочел не запускать отдельные запросы для получить функциональность, которую я описывал

+0

Почему подзапрос? Почему бы вам не присоединиться к адресам? – outis

+0

@outis, я не совсем уверен, что отвечает на мой вопрос, но не могли бы вы привести пример? Мой SQl не самый большой – iangraham

ответ

4

Чтобы ответить на ваш вопрос в комментариях, вот запрос я бы себе:

SELECT 
    users.name, users.email, 
    addresses.street, addresses.city, addresses.state, addresses.zip 
    FROM users  
    LEFT JOIN addresses 
    ON users.id = addresses.user_id 
    WHERE users.id = 1 

Поскольку суб-выбор является в большинстве проекции таблицы адресов, это кажется излишним.

Что касается основного вопроса, мне трудно найти что-нибудь элегантное и не-хаки. На самом деле, единственные вещи, которые приходят на ум, совершенно безобразны. Можно, например, добавить префиксы к именам столбцов в запросе:

SELECT 
    users.name AS user_name, users.email AS user_email, 
    addresses.street AS address_street, ... 

Вы должны были бы разобрать имена столбцов самостоятельно. Полагаю, это будет не так уж плохо. Что-то вроде:

function rowToObject($row) { 
    $obj = new StdClass(); 
    foreach ($row as $key => $val) { 
     $keys = explode('_', $key); 
     $o = $obj; 
     for ($i=0; count($keys) > 1; ++$i) { 
      $k = array_shift($keys);    
      if (! isset($o->{$k})) { 
      $o->{$k} = new StdClass(); 
      } 
      $o = $o->{$k}; 
     } 
     $o->{$keys[0]} = $val; 
    } 
    return $obj; 
} 

... 
$result = rowToObject($mysql->query($query)->fetch_assoc()); 
+0

, поэтому этот запрос выбирает все из таблицы адресов? Я не знал, что ты можешь это сделать. благодаря! – iangraham

+0

Он выбирает каждый адрес с указанным вами user_id, который совпадает с вашим запросом. – outis

0

Я думаю, что, возможно, единственный способ - использовать некоторый ORM (Object Relational Mapper). Использование ORM приносит другие полезные вещи, чем это, но вы должны заплатить за это с меньшей производительностью.

Хорошие PHP ORM, например. Doctrine или Propel.

Смежные вопросы