Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Symfony]SF2 return json...
Szymciosek
post
Post #1





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Witam,
chciałem zobaczyć jak Symfony2 poradzi sobie jako API i w tym celu chciałem wykorzystać ActionScript3.0 + Symfony2 (PHP) więc mam sobie jakąś aplikację, która wysyła z flasha json ( { id:1 } )
więc flash oczekuje wszystkich kolumn, które należą do ID = 1. Jako z tym nie mam problemu, bo normalnie mogę zrobić to tak:

  1. $json = json_decode($_POST['data']); //odebranie json z flash
  2.  
  3. $query = mysql_query("SELECT * FROM user WHERE id=$json->id"); //zapytanie do bazy
  4.  
  5. while($data = mysql_fetch_object($query))
  6. {
  7. $object = array(
  8. 'user' => $data,
  9. );
  10. } //uzupełnienie tablicy $object danymi z bazy
  11. print json_encode($object); //zwrócenie json do flasha


ale jak to samo zrobić w Symfony2 ?

  1. <?php
  2.  
  3. namespace SimonMedia\ApiBundle\Controller;
  4.  
  5. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  6. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  7. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  8.  
  9. class DefaultController extends Controller
  10. {
  11. /**
  12.   * @Route("/")
  13.   * @Template()
  14.   */
  15. public function indexAction()
  16. {
  17. return array();
  18. }
  19.  
  20. /**
  21.   * @Route("/user/get/all")
  22.   */
  23. public function getAll()
  24. {
  25. $em = $this->getDoctrine()->getEntityManager();
  26. $entities = $em->getRepository('SimonMediaApiBundle:Userzy')->findAll();
  27.  
  28. var_dump($entities);
  29. }
  30. }


var_dump zwraca
  1. array (size=3)
  2. 0 =>
  3. object(SimonMedia\ApiBundle\Entity\Userzy)[211]
  4. private 'id' => int 1
  5. private 'name' => string 'Janusz' (length=6)
  6. private 'email' => string 'Janko@wp.pl' (length=11)
  7. private 'phone' => string '668559634' (length=9)
  8. 1 =>
  9. object(SimonMedia\ApiBundle\Entity\Userzy)[206]
  10. private 'id' => int 2
  11. private 'name' => string 'Marek' (length=5)
  12. private 'email' => string 'Maro@wp.pl' (length=10)
  13. private 'phone' => string '665583999' (length=9)
  14. 2 =>
  15. object(SimonMedia\ApiBundle\Entity\Userzy)[207]
  16. private 'id' => int 3
  17. private 'name' => string 'Mariusz' (length=7)
  18. private 'email' => string 'Mario@wp.pl' (length=11)
  19. private 'phone' => string '994888777' (length=9)


Ale nijak nie potrafię się po tym ruszyć...

EDIT::
Doszedłem do tego, że po zmianie w klasie Userzy.php (entity) z private na public mam dostęp do np

print $entities[0]->name;

w przeciwnym razie otrzymuję error
Cannot access private property SimonMedia\ApiBundle\Entity\Userzy::$name in F:\WORK\labs\Symfony\ApiID\src\SimonMedia\ApiBundle\Controller\DefaultController.php on line 28

Ale chyba taka zmiana nie jest dobra i nie na tym to ma polegać ?

Ten post edytował Szymciosek 16.09.2012, 11:06:44
Go to the top of the page
+Quote Post
marcio
post
Post #2





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


Pokaz klase entity, powinienes w niej miec gettery/settery zeby uzywac wlasciwosci klas private


--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
Szymciosek
post
Post #3





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Owszem mam.

  1. Owszem mam.
  2.  
  3. <?php
  4.  
  5. namespace SimonMedia\ApiBundle\Entity;
  6.  
  7. use Doctrine\ORM\Mapping as ORM;
  8.  
  9. /**
  10.  * SimonMedia\ApiBundle\Entity\Userzy
  11.  *
  12.  * @ORM\Table()
  13.  * @ORM\Entity(repositoryClass="SimonMedia\ApiBundle\Entity\UserzyRepository")
  14.  */
  15. class Userzy
  16. {
  17. /**
  18.   * @var integer $id
  19.   *
  20.   * @ORM\Column(name="id", type="integer")
  21.   * @ORM\Id
  22.   * @ORM\GeneratedValue(strategy="AUTO")
  23.   */
  24. private $id;
  25.  
  26. /**
  27.   * @var string $name
  28.   *
  29.   * @ORM\Column(name="name", type="string", length=255)
  30.   */
  31. private $name;
  32.  
  33. /**
  34.   * @var string $email
  35.   *
  36.   * @ORM\Column(name="email", type="string", length=255)
  37.   */
  38. private $email;
  39.  
  40. /**
  41.   * @var string $phone
  42.   *
  43.   * @ORM\Column(name="phone", type="string", length=255)
  44.   */
  45. private $phone;
  46.  
  47.  
  48. /**
  49.   * Get id
  50.   *
  51.   * @return integer
  52.   */
  53. public function getId()
  54. {
  55. return $this->id;
  56. }
  57.  
  58. /**
  59.   * Set name
  60.   *
  61.   * @param string $name
  62.   */
  63. public function setName($name)
  64. {
  65. $this->name = $name;
  66. }
  67.  
  68. /**
  69.   * Get name
  70.   *
  71.   * @return string
  72.   */
  73. public function getName()
  74. {
  75. return $this->name;
  76. }
  77.  
  78. /**
  79.   * Set email
  80.   *
  81.   * @param string $email
  82.   */
  83. public function setEmail($email)
  84. {
  85. $this->email = $email;
  86. }
  87.  
  88. /**
  89.   * Get email
  90.   *
  91.   * @return string
  92.   */
  93. public function getEmail()
  94. {
  95. return $this->email;
  96. }
  97.  
  98. /**
  99.   * Set phone
  100.   *
  101.   * @param string $phone
  102.   */
  103. public function setPhone($phone)
  104. {
  105. $this->phone = $phone;
  106. }
  107.  
  108. /**
  109.   * Get phone
  110.   *
  111.   * @return string
  112.   */
  113. public function getPhone()
  114. {
  115. return $this->phone;
  116. }
  117. }
Go to the top of the page
+Quote Post
marcio
post
Post #4





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


Nie rozumiem.

Robisz petle na obiekcie i potem wywolujesz gettery


--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
Szymciosek
post
Post #5





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Czyli jak ?
Mam problem nawet z dostaniem się do pojedynczej wartości z array/object a o pętli nie wspomnę...

Chociaż chwila, bo chyba coś mam...

Ten post edytował Szymciosek 16.09.2012, 13:07:32
Go to the top of the page
+Quote Post
m44
post
Post #6





Grupa: Zarejestrowani
Postów: 63
Pomógł: 10
Dołączył: 16.11.2008

Ostrzeżenie: (0%)
-----


Tworzysz sobie w repozytorium "Userzy" metodę, która zwraca kolekcję użytkowników jako tablicę.
W kontrolerze przekazujesz zmienną do widoku. Jeśli chcesz używać adnotacji @Template nie zapomnij, żeby w szablonie przekonwertować tą zmienną do json.
Możesz też od razu w repozytorium potraktować zwróconą kolekcję json_encode, jak zrobisz zależy od Twojej organizacji kodu.

Inna ważna sprawa, to odpowiedni nagłówek w odpowiedzi zwrotnej. Możesz w routingu zdefiniować domyślny parametr, który nazywa się "_format" i wtedy Symfony automatycznie wyśle odpowiedni nagłówek.
Możesz też ustawić nagłówek bezpośrednio w kontrolerze manipulując obiektem Response. Nie zapominaj, że kontroler w Symfony powinien zwrócić obiekt Response, a to czy go zwracasz pomagając sobie adnotacjami, czy przez metody pomocnicze kontrolera to sprawa drugorzędna.

Nie rozumiem, dlaczego próbujesz dostać się do właściwości obiektu nie używając metod dostępowych. Przecież operujesz na obiektach, wiec po to masz w klasie Entity metody dostępowe (get* i set*), żeby ich używać, a nie bezpośrednio używać prywatnych czy chronionych właściwości.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #7





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Możesz powiedzieć coś więcej o tej metodzie ?

Potrzebuję uzyskać coś takiego:
Kod
{ user: [ {name:Janusz}, {name:Marek}, {name:Mariusz} ] }


a na razie mam:
Kod
{"user":{"name":"Mariusz"}}

za pomocą takiego kodu, co w ogóle nie jest zautomatyzowane za bardzo...
  1. foreach ($entities as $entity)
  2. {
  3. $data = array(
  4. 'user' => array(
  5. 'name' => $entity->getName()
  6. ),
  7. );
  8. }
  9. print json_encode($data);
Go to the top of the page
+Quote Post
phpion
post
Post #8





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Podstawy budowy tablic się kłaniają...
  1. $data['user'][] = array('name' => $entity->getName());
Go to the top of the page
+Quote Post
Szymciosek
post
Post #9





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Z takim problemem sobie poradziłem i działa ok dzięki wam, ale mam następny problem, w poprzednim miałem podane ID, a teraz potrzebuję skorzystać z findAll();

doszedłem do takiego miejsca i dalej nie wiem co...

  1. foreach ($entities as $entity)
  2. {
  3. //tak powinno wyglądać
  4. //$data[] = array('name' => $entity->getName(), 'phone' => $entity->getPhone());
  5. foreach ($cols as $col)
  6. {
  7. $method = 'get' . $col;
  8. $data[] = array($col => $entity->$method());
  9. print_r($data);
  10. }
  11. }


Niestety zwracana $data w postaci json wygląda tak:
Kod
{"data":{"users":[{"name":"Janusz"},{"phone":"668559634"},{"name":"Marek"},{"phone":"665583999"},{"name":"Mariusz"},{"phone":"994888777"}]}}


a powinien:
Kod
{"data":{"users":[{"name":"Janusz","phone":"668559634"},{"name":"Marek","phone":"665583999"},{"name":"Mariusz","phone":"994888777"}]}}


Czyli gdzieś za dużo razy tworzony jest array, zakładam, że w drugiej pętli foreach, ale tak jakoś musiałbym to mieć...

tablica $cols jest tworzona:
  1. foreach ($this->getDataFromPost()->cols as $col)
  2. {
  3. $cols[] = $col;
  4. }


Kombinowałem na różne sposoby z $data[$cols], $data = array..., $data[], explode, ale nie mogę wpaść na pomysł jak to rozwiązać...

Proszę o pomoc.
Go to the top of the page
+Quote Post
marcio
post
Post #10





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


Tak na szybko:
  1. foreach ($cols as $key => $value)
  2. {
  3. $method = 'get' . $value;
  4. $data[] = array($key => $entity->$method());
  5. print_r($data);
  6. }

Albo jakos tak nie wiem dokladnie jak wyglada $cols.


--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
phpion
post
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Może warto najpierw zapoznać się z podstawami PHP, a nie rzucać się od razu na frameworka i to na dodatek takiego, który do najprostszych nie należy. Masz problem, gdyż za każdym razem dokładasz nowy element do tablicy "głównej". Wewnątrz drugiej pętli powinieneś stworzyć strukturę pojedynczego użytkownika, a poza tą pętlą dokładać ją do tablicy głównej. Wykorzystaj zatem jeszcze jedną tablicę pomocniczą. Nie zapomnij jednak o jej zerowaniu w odpowiednim miejscu. Kombinuj!
Go to the top of the page
+Quote Post
Szymciosek
post
Post #12





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Niestety, próbowałem już chyba na wszystkie sposoby, próbuję od 2 dobrych dni... i bezskutecznie...

teraz po Twojej wypowiedzi próbowałem coś na wzór:
  1. foreach ($this->getDataFromPost()->cols as $col)
  2. {
  3. $method = 'get' . $col;
  4. }
  5.  
  6. foreach ($entities as $entity)
  7. {
  8. foreach ($this->getDataFromPost()->cols as $col)
  9. {
  10. $method = 'get' . $col;
  11. $methods[] = $method;
  12. $cols[] = $col;
  13. }
  14.  
  15. for ($i = 0; $i < count($methods); $i++)
  16. {
  17. $tmp[] = array('name' => $entity->$methods[$i]());
  18. }
  19.  
  20. $data[] = $tmp;
  21. $tmp = array();
  22.  
  23. $cols = array();
  24. $methods = array();
  25. }


lecz też bezskutecznie, bo otrzymuję:
Kod
{"data":{"users":[[{"name":"Janusz"},{"name":"668559634"}],[{"name":"Marek"},{"name":"665583999"}],[{"name":"Mariusz"},{"name":"994888777"}]]}}
, a miałoby to być parami, do tego miałoby to być name, phone, name, phone, name, phone itd...

cols wygląda tak:
Kod
Array
(
    [0] => name
    [1] => phone
)


Zaprzęgnąłem do tego również znajomego, który jest o wiele lepszym programistą ode mnie, ale niestety też nie pomógł... Czy to w ogóle jest możliwe do zrobienia ?
Przepraszam za zawracanie wam tyłka, ale naprawdę już nie wiem co i jak zrobić żeby to osiągnąć... szukam, czytam o tablicach, próbuję swoimi sposobami, spróbówałem z $tmp i nic...

Ten post edytował Szymciosek 20.09.2012, 17:01:08
Go to the top of the page
+Quote Post
phpion
post
Post #13





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Spróbuj tego:
  1. $data = array(
  2. 'data' => array(
  3. 'users' => array()
  4. )
  5. );
  6.  
  7. foreach ($entities as $entity) {
  8. $tmp = array();
  9.  
  10. foreach ($this->getDataFromPost()->cols as $col) {
  11. $method = 'get'.$col;
  12.  
  13. $tmp[$col] = $entity->$method();
  14. }
  15.  
  16. $data['data']['users'][] = $tmp;
  17. }

Pisane oczywiście w ciemno, ale wydaje mi się, że powinno być ok.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #14





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Działa bardzo dobrze, ale chyba nie wpadłbym na to tak szybko, chociaż z tego co widzę - co zrobiłem - to krążyłem bardzo blisko chyba ?
Dziękuję Ci bardzo dobry człowieku wink.gif


Czyli albo źle składałem $tmp, albo źle później składałem $data itd...

Ten post edytował Szymciosek 20.09.2012, 18:25:11
Go to the top of the page
+Quote Post
netrat
post
Post #15





Grupa: Zarejestrowani
Postów: 14
Pomógł: 2
Dołączył: 1.10.2012
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Osobiście sugerowałbym wpierw zbudowanie odpowiedniej tablicy, z encji poprzez użycie metody toArray() którą można sobie zdefiniować w modelu a następnie zwrócenie odpowiedniego response. Trochę może zamotałem więc pokaże w kodzie o co mi chodzi
  1. $responseArray = array();
  2. foreach ($listaElementół as $element){
  3. $responseArray[] = $element->toArray();
  4. }
  5. $response = new Response(json_encode( $responseArray ));
  6. $response->headers->set('Content-Type', 'application/json');
  7. return $response;

Tu już chodzi mi tylko o to aby rozwiązanie było nieco bardziej eleganckie smile.gif

Ten post edytował netrat 1.10.2012, 20:59:01
Go to the top of the page
+Quote Post
Szymciosek
post
Post #16





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


No a jak wtedy wygląda metoda toArray ?
Go to the top of the page
+Quote Post
ano
post
Post #17





Grupa: Zarejestrowani
Postów: 435
Pomógł: 40
Dołączył: 16.02.2003
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Zamiast ręcznie transformować obiekty na tablice, potem json_encode to radzę zainteresować się świetnym Bundlem:
http://jmsyst.com/bundles/JMSSerializerBundle
Adnotacjami w modelach oznaczasz jak ma być serializowany/deserializowany. A potem bezproblemowo serializujesz do xmla/jsona.


--------------------
Linkedin | ...
Go to the top of the page
+Quote Post
Szymciosek
post
Post #18





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Witam ponownie, nie chciałem zakładać nowego tematu tylko zapytam tutaj.

Jak sprawdzić czy dana kolumna istnieje nie pobierając z entity wszystkich danych ?

Tzn. mam takiego coś:
  1. $entityManager = $this->getDoctrine()->getEntityManager();
  2. $entities = $entityManager->getRepository('ApiRestServiceBundle:Users');


i teraz jeśli zrobię
  1. var_dump($entitites);


otrzymuję:
Kod
object(Doctrine\ORM\EntityRepository)[364]
      ...
      public 'fieldNames' =>
        array (size=13)
          'id' => string 'id' (length=2)
          'username' => string 'username' (length=8)
          'first_name' => string 'first_name' (length=10)
          'last_name' => string 'last_name' (length=9)
          'email_address' => string 'email_address' (length=13)
          'locale' => string 'locale' (length=6)
          'password' => string 'password' (length=8)
          'created' => string 'created' (length=7)
          'last_login' => string 'last_login' (length=10)
          'user_rank' => string 'user_rank' (length=9)
          'active' => string 'active' (length=6)
          'user_token' => string 'user_token' (length=10)
          'ip_address' => string 'ip_address' (length=10)
      public 'columnNames' =>
        array (size=13)
          'id' => string 'id' (length=2)
          'username' => string 'username' (length=8)
          'first_name' => string 'first_name' (length=10)
          'last_name' => string 'last_name' (length=9)
          'email_address' => string 'email_address' (length=13)
          'locale' => string 'locale' (length=6)
          'password' => string 'password' (length=8)
          'created' => string 'created' (length=7)
          'last_login' => string 'last_login' (length=10)
          'user_rank' => string 'user_rank' (length=9)
          'active' => string 'active' (length=6)
          'user_token' => string 'user_token' (length=10)
          'ip_address' => string 'ip_address' (length=10)
      ...


I oczywiście chce się dostać do fieldNames lub columnNames, bo widzę, że to, to samo więc nie powinno robić różnicy, które wybiorę.

Podczas pobrania wszystkich danych za pomocą findAll() zadanie byłoby ułatwione, bo dostanę wtedy wszystkie kolumny i ich wartości, lecz nie o to mi chodzi, bo przyjdzie sytuacja, w której będę musiał pobrać tylko username i first_name i co wtedy ?

Za pomocą createQuery("SHOW COLUMNS... nie jestem w stanie tego zrobić, bo wywala mi błąd, że takie rzeczy jak INSERT INTO czy właśnie SHOW, bo otrzymuję: [Syntax Error] line 0, col 0: Error: Expected SELECT, UPDATE or DELETE, got 'SHOW'

Ten post edytował Szymciosek 13.10.2012, 14:00:58
Go to the top of the page
+Quote Post
m44
post
Post #19





Grupa: Zarejestrowani
Postów: 63
Pomógł: 10
Dołączył: 16.11.2008

Ostrzeżenie: (0%)
-----


To wszystko jest opisane w dokumentacji Doctrine.

Z treści twojego pytania nie wiadomo, czy chcesz sprawdzić, czy kolumna fizycznie istnieje w bazie, czy tylko chcesz wybrać wybrane kolumny podczas budowania zapytania.
Zrozumiałem, że chodzi o to drugie. W takim wypadku tworzysz sobie w twoim repozytorium metodę zwracającą to co ma zwracać, np. za pomocą QueryBuilder.
Go to the top of the page
+Quote Post
Szymciosek
post
Post #20





Grupa: Zarejestrowani
Postów: 1 168
Pomógł: 126
Dołączył: 5.02.2010
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Właśnie chodzi o to czy kolumna istnieje w bazie, bo żeby wszystko zadziałało Entity musi być zbudowane na podstawie bazy, więc musi z nią współpracować.

Normalnie zrobiłbym np. coś w tym stylu:
Kod
SHOW COLUMNS FROM users WHERE Field='id';


następnie sprawdzał czy zapytanie coś zwraca i jeśli zwraca, to istnieje, jeśli nie to error.

Równie dobrze mogę sprawdzać czy istnieje metoda w klasie Entity, ale to rozwiązanie nie jest dobre, bo musiałbym przelecieć przez array w pętli i sprawdzać, które istnieją itd...

m44 możesz powiedzieć coś więcej ?

Ten post edytował Szymciosek 13.10.2012, 20:03:16
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 13:19