2013-03-04 5 views
8

Powiedzmy mam 2 obiekty PHP:PDO FETCH_CLASS z połączonych tabel

<?php 
class Post { 
    public $id; 
    public $text; 
    public $user_id; 
} 
?> 

i

<?php 
class User { 
    public $id 
    public $name 
} 
?> 

Każdy post ma unikalną ograniczenie z 1 użytkownika w bazie danych.

Chcę wypełnić dane w obiekcie "Post" - obiekt z PDO "FETCH_CLASS", który działa dla wszystkich atrybutów "Post", ale jak wypełnić atrybuty w "User"?

Moja instrukcja_sql wygląda następująco:

SELECT post.id, 
     post.text, 
     post.user_id, 
     user.id, 
     user.name 
FROM POST INNER JOIN User on post.user_id = user.id 

Dzięki!

UPDATE:

ATM wypełnić mój "post" -class tak:

$statement = $db -> prepare($query); 
    $statement -> execute(); 
    $statement -> setFetchMode(PDO::FETCH_CLASS, 'Post'); 
    $posts = $statement -> fetchAll(); 

Więc jak będę musiał zmienić również do wypełniania innej klasy "Użytkownik"?

ROZWIĄZANIE:

$statement = $db -> prepare($query); 
$statement -> execute(); 
$posts = array(); 
while (($row = $statement->fetch(PDO::FETCH_ASSOC)) !== false) { 
    $post   = new Post(); 
    $post->id  = $row['post_id']; 
    $post->text  = $row['post_text']; 
    $post->created = $row['post_created']; 
    $post->image = $row['post_image']; 
    $post->url  = $row['post_url']; 
    $post->weight = $row['post_weight']; 
    $post->likes = $row['post_likes']; 
    $user   = new User(); 
    $user->id  = $row['user_id']; 
    $user->nickname = $row['user_nickname']; 
    $user->created= $row['user_created']; 
    $user->locked = $row['user_locked']; 
    $post->user  = $user; 
    $posts[] = $post; 
} 
return $posts; 
+0

Twoje pytanie bardzo pomogło! Dziękuję Ci! –

Odpowiedz

2

Tam nie ma wsparcia dla bezpośrednio w PDO ile jestem świadomy. Zazwyczaj, jeśli potrzebujesz utworzyć złożony wykres obiektów z wyniku zapytania, który jest odpowiedzialny za ORM.

Jeśli potrzebujesz tej funkcji, polecam użyć Doctrine lub Propel, zamiast pisać coś samemu. Są też inne, które mogą być lżejsze, ale nie mam z nimi doświadczenia.

EDIT:

Myślę, że może ja źle na pytanie, jestem pewien, inni mogą. Myślę, że prawdziwe pytanie brzmiało, jak uzyskać dostęp do połączonych kolumn, a nie w sposób szesnastkowy, jak utworzyć z nich obiekt.

W takim przypadku zwykłe użycie standardowej metody arsefeth, takiej jak PDO::FETCH_ASSOC, PDO::FETCH_NUMERIC lub PDO::FETCH_BOTH spowoduje wyświetlenie wszystkich kolumn, które wysłałeś.

Jeśli chcesz zmienić to w "wykres obiektowy", musisz to zrobić ręcznie, nie używając PDO::FETCH_CLASS.

Na przykład:

//$db is pdo: 
// also notice im aliase the columns prefixing the name so that we can tell what belongs to 
// post and what belongs to user, an alternative approach would be to use FETCH_NUMERIC, 
// which just uses the column positions from the seelct statement as the keys 
// so in this case post.id would be in the array as key 0, and user.name would be in the 
// array as key 4 
$stmt = $db->prepare('SELECT post.id as p_id, 
     post.text as p_text, 
     post.user_id as p_user_id, 
     user.id as u_id, 
     user.name as u_name 
FROM POST INNER JOIN User on post.user_id = user.id'); 

$stmt->execute(); 

while (($row = $stmt->fetch(PDO::FETCH_ASSOC)) !== false) { 
    print_r($row); 
    /* will output: 
     Array (
     'p_id' => 'value' 
     'p_text' => 'value' 
     'p_user_id' => 'value' 
     'u_id' => 'value', 
     'u_name' => 'value' 
    ) 
    So now you need to decide how to create your objects with the information returned 
    */ 
} 
+0

dzięki.ATM Myślę, że powinienem był trzymać się z dala od PDO, jeśli jest to zbyt "skomplikowane". Jakie aplikacje istnieją nawet bez prostego łączenia? –

+0

Nie rozumiem, co jest tak skomplikowane, biorąc pod uwagę, że jedyną opcją jest "mysqli", z którym jest trudniej pracować i jest bardziej gadatliwy. Żadna z nich nie "nawilża" złożonej relacji z połączonego wyniku zapytania. – prodigitalson

+0

Nie jestem pewien, czy dobrze rozumiem Twój komentarz. Czy zgadzasz się, że PDO powinien to wspierać? Czy obsługuje go, gdy nie używa FETCH_CLASS? Zajmę się tym teraz ... –

1

Nie naprawdę odpowiedzią na OQ, ale ponieważ utrzymuje pojawiały się w Google (tak wiem, że ponad rok życia). Przekonasz się, że NIESAMOWITE szybciej jest po prostu pominąć pętle i osobno przetestować każdą tabelę.

 

    SELECT post.id, 
      post.text, 
      post.user_id, 
    FROM POST INNER JOIN User on post.user_id = user.id 
     $statement = $db -> prepare($query); 
     $statement -> execute(); 
     $statement -> setFetchMode(PDO::FETCH_CLASS, 'Post'); 
     $posts = $statement -> fetchAll(); 

    SELECT user.id, 
      user.name 
    FROM POST INNER JOIN User on post.user_id = user.id 
     $statement = $db -> prepare($query); 
     $statement -> execute(); 
     $statement -> setFetchMode(PDO::FETCH_CLASS, 'User'); 
     $users = $statement -> fetchAll(); 
0

Może używać PDO :: FETCH_NAMED, jeśli pracujesz w wielu tabelach. Lub użyj PDO :: ATTR_FETCH_TABLE_NAMES.