Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Powtórzone wartości z wiersza do jednego DIVa
Forum PHP.pl > Forum > Przedszkole
sadistic_son
Cześć,
Tabela typu produktu wygląda mniej więcej tak:
ID | type | i tak dalej
1 | dvd | xx
2 | book | yy
3 | furniture | zz
4 | furniture | aa
5 | furniture | bb

Wyświetlam z bazy te dane i wrzucam w DIVy. Chcę zrobić tak aby dla wartości które się nie powtarzają każda lądowała do oddzielnego DIVa (dvd, book) a te które występują więcej niż raz żeby lądowały do jednego wspólnego diva (furniture). Chcę osiągnąć takie coś:
  1. <div id="book">1 - xx</div>
  2. <div id="dvd">2 - yy</div>
  3. <div id="furniture">3 - zz | 4 - aa | 5 - bb</div>

Kombinuję z IFami i zmiennymi pomocniczymi, gdzie zapisuję do zmiennej type (dvd, book, furniture) aktualnie iterowanego w pętli wiersza i porównuję w następnej iteracji czy są takie same. Jeśli tak, to wiadomo że powinna wylądować do już istniejącego DIVa. Ale problem w tym, że przecież taki DIV trzeba najpierw otworzyć a potem zamknąć. I tutaj już się moja metoda nie sprawda.
Naprowadźcie pls.
Dzięki.

nospor
Powinienies zaczac od prawidlowego przygotowania danych, czyli pogrupowania, a potem wyswietlanie to bajka
Tu masz opisane przykladowe grupowanie
http://nospor.pl/grupowanie-wynikow.html
sadistic_son
Ok, Twój samouczek jest dla mnie jasny i chętnie bym z niego skorzystał, ale niestety muszę to zrobić obiektowo. I tutaj pojawia się dla mnie trudność.

Tak wygląda wycinek mojej klasy, w której generalnie listuję większość rzeczy:
  1. namespace nameOne;
  2.  
  3. class ProductAdd
  4. {
  5.  
  6.  
  7. public function listFullProperties()
  8. {
  9. $properties = $this->getFullProperties();
  10. return $properties;
  11. }
  12. private function getFullProperties()
  13. {
  14. $db = new DB();
  15. $db->query("SELECT * FROM property ORDER BY type ASC");
  16. $results = $db->resultSet();
  17. return $results;
  18. }
  19.  
  20. }


Tutaj jest metoda resultSet(); z klasy DB:
  1. class DB
  2. {
  3. private $dbh;
  4. private $stmt;
  5.  
  6. public function __construct()
  7. {
  8. $this->dbh = new \PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS);
  9. }
  10.  
  11. public function resultSet()
  12. {
  13. $this->execute();
  14. return $this->stmt->fetchAll(\PDO::FETCH_ASSOC);
  15. }
  16.  
  17. }


Klasę DB zmodyfikowałem na własny użytek na podstawie kursu OOP który przed świętami robiłem. Tak więc sam tego nie wymyśliłem, ale rozumiem co tam się dzieje. Niestety dla mnie, zamiast starego poczciwego while ($row = mysql_fetch_array($res)) mamy tutaj metody i obiekty, z którymi jeszcze nie jestem jakoś ekstra zaznajomiony. a PDO to dla mnie na razie niemalże czarna magia - wiem że jest, potrafię w prostym przykładzie użyć i to tyle.
Jak powyższe zmodyfikować, aby uzyskać pogrupowane wyniki, tak jak to opisałeś?
nospor
Tutaj

private function getFullProperties()
{
$db = new DB();
$db->query("SELECT * FROM property ORDER BY type ASC");
$results = $db->resultSet();
return $results;
}

w $results masz teraz tablice swoja. No to dopisz teraz metode w tej klasie ktora pogrupuje te tablice. To nei ma znaczenia czy to jest klasa czy nie. Metoda to metoda

zamiast mojego

while ($row = mysql_fetch_array($res)){

ty lecisz FOREACH po $results i tyle. petla to petla. Jak to sam mowisz, zadne rocket sience
sadistic_son
Hmm, no w sumie logiczne. Dzięki za pomoc, muszę teraz lecieć z córką na basen ale wieczorem przysiądę do tego.

OK, elegancko grupuje. Posłużyłem się przykładem 2. Jednakże mam teraz problem aby wyświetlić pozostałe kolumny z bazy. Przy jednej wartości (w przykładzie 'name-miasto' u mnie 'property.property') to jest ok. Ale z tabeli property mam do wyświetlenia jeszcze type, label i description.
Posługując się przykladem 2 nospora, w linijce 12 mamy $name = $row['NAME']; i to tutaj mogę dodać wartości pozostałych kolumn, jednakże jako string, a przeciez potrzebuję aby wartość z każdej kolumny była oddzielną zmienną, lub elementem tablicy.
Mozna zrobić tak w linijce 12 z przykładu 2:
  1. $name = array();
  2. $name[] = $row['NAME'];
  3. $name[] = $row['DESCRIPTION'];
  4. $name[] = $row['kolejnaKolumna'];

Ale to uniemożliwia wyświetlenie danych w 2 foreachach bo robi się tablica z kolejnym wymiarem.
Naprowadźcie pls.
Thx.
nospor
pokaz caly kod co teraz masz bo nie kumam problemu

No i skoro twoja struktura ma przechowywac wiecej info to powinienies raczej isc w kierunku przykladu 1 a nie 2. no i pamietaj, to tylko przyklady, przeciez ty mozesz dodawac tam weicej info
sadistic_son
Kawałek klasy ProductAdd:
  1. private function getFullProperties()
  2. {
  3. $db = new DB();
  4. $db->query("SELECT * FROM property ORDER BY type ASC");
  5. $results = $db->resultSet();
  6. return $results;
  7. }
  8.  
  9. public function groupFullProperties()
  10. {
  11. $properties = array();
  12. foreach ($this->getFullProperties() as $row) {
  13. $property = $row['property'];
  14.  
  15. $newProperty = $row['type'];
  16. if (!isset($properties[$newProperty])) {
  17. $properties[$newProperty] = array();
  18. }
  19. $properties[$newProperty][] = $property;
  20.  
  21. }
  22. return $properties;
  23. }


wyświetlanie pogrupowanych wartości:
  1.  
  2. foreach ($properties->groupFullProperties() as $type => $property) {
  3. echo '<div style="border:1px solid red; margin:5px 0 0 5px;" class="TEMPdynamicFields" id="">' . $type . '';
  4. foreach ($property as $oneProperty) {
  5. echo '<div style="margin:5px 0 0 5px;">' . $oneProperty . '</div>';
  6.  
  7. }
  8. echo '</div>';
  9. }


Powyższe działa, ale...
W groupFullProperties() powinienem mieć jeszcze pozostałe wartości z wiersza. Uff, zmęczyłem się, idę na fajkę.



Cytat
przeciez ty mozesz dodawac tam weicej info

No właśnie jakośc nie mogę wpaść w którym miejscu w metodzie. Może dodatkowy poziom nikotyny pomoże...
nospor
A gdzie sa inne kolumny/dane co chciales dodac?
sadistic_son
No w powyższym nie ma (bo to działa), natomiast pisałem, że próbowałem je dodać w taki sposób:
  1. //linijka 13 z klasy ProductAdd
  2. $property = $row['property'].' '.$row['type'];
Ale wiadomo, teraz mam zwykły string, a nie o to chodzi.

Lub w taki sposób:
  1. //od linijki 13 z klasy ProductAdd
  2. $property['property'] = $row['property'];
  3. $property['type'] = $row['type'];
  4.  
  5. //linijka 19
  6. $properties[$newProperty]['property'] = $property['property'];
  7. $properties[$newProperty]['type'] = $property['type'];

Obie metody złe sad.gif
nospor
pokaz mi co dokladnie zawiera $row

print_r($row);
sadistic_son
var_dump($row);

Kod
array(5) {
  ["id"]=>
  int(1)
  ["type"]=>
  string(4) "Book"
  ["property"]=>
  string(6) "weight"
  ["description"]=>
  string(40) "Please provide the weight of book in kg."
  ["label"]=>
  string(11) "Weight (kg)"
}
array(5) {
  ["id"]=>
  int(2)
  ["type"]=>
  string(3) "DVD"
  ["property"]=>
  string(4) "size"
  ["description"]=>
  string(33) "Please provide size of DVD in MB."
  ["label"]=>
  string(9) "Size (MB)"
}
array(5) {
  ["id"]=>
  int(3)
  ["type"]=>
  string(9) "Furniture"
  ["property"]=>
  string(5) "width"
  ["description"]=>
  string(42) "Please provide dimentions in HxWxL format."
  ["label"]=>
  string(10) "Width (cm)"
}
array(5) {
  ["id"]=>
  int(4)
  ["type"]=>
  string(9) "Furniture"
  ["property"]=>
  string(6) "height"
  ["description"]=>
  string(42) "Please provide dimentions in HxWxL format."
  ["label"]=>
  string(11) "Height (cm)"
}
array(5) {
  ["id"]=>
  int(5)
  ["type"]=>
  string(9) "Furniture"
  ["property"]=>
  string(6) "length"
  ["description"]=>
  string(42) "Please provide dimentions in HxWxL format."
  ["label"]=>
  string(11) "Length (cm)"
}
NULL

Zabieram się za analizę tego.
nospor
No to zamiast tylko nazwy property, wrzucaj tez wszustkie inne rzeczy dla tej property, czyli jako tablice a nie jako text

  1. foreach ($this->getFullProperties() as $row) {
  2. $property = $row['property'];
  3.  
  4. $newProperty = $row['type'];
  5. if (!isset($properties[$newProperty])) {
  6. $properties[$newProperty] = array();
  7. }
  8. $properties[$newProperty][] = [
  9. 'property' => $property,
  10. 'label' => $row['label'],
  11. 'description' => $row['description']
  12.  
  13. ];
  14.  
  15. }

I juz. No tu naprawde nie ma zadnej filozofii. wink.gif
sadistic_son
A, ok.
ale to wtedy jeszcze wyświetlanie trzeba zmodyfikować:
  1. foreach ($properties->groupFullProperties() as $type => $property) {
  2. echo '<div style="border:1px solid red; margin:5px 0 0 5px;" class="TEMPdynamicFields" id="">' . $type . '';
  3. foreach ($property as $oneProperty) {
  4. foreach($oneProperty as $p)
  5. echo '<div style="margin:5px 0 0 5px;">' . $p . '</div>';
  6.  
  7. }
  8. echo '</div>';
  9. }


No filozofii nie ma, ale jak tak się posiedzi nad tym to łeb puchnie i czasem ciężko wpaść na rozwiązanie sad.gif
nospor
Cytat
ale to wtedy jeszcze wyświetlanie trzeba zmodyfikować:

To straszne tongue.gif
sadistic_son
Działa. Kurde dzięki nospor, naprawdę doceniam twoja pomoc.

Miałbym jeszcze jedno pytanie co do powyższego.
Przy 'type' == 'Furniture' chciałbym żeby 'description' było wyświetlane tylko raz, dla ostatniego row. Naprowadź pls.
Może na początku pętli $i=0; a w pętli $i++; i jeśli $i != 0 to nie wyświetlać description? Ale wtedy mi tylko pierwsze wyświetli a nie istatnie.
nospor
Cytat
Miałbym jeszcze jedno pytanie co do powyższego.
Przy 'type' == 'Furniture' chciałbym żeby 'description' było wyświetlane tylko raz, dla ostatniego row. Naprowadź pls.

Pokaz kod wyswietlania po zmianach
sadistic_son
Tak wygląda wyświetlanie:

  1. foreach ($properties->groupFullProperties() as $type => $property) {
  2. echo '<div style="border:1px solid red; margin:5px 0 0 5px;" class="dynamicFields" id="'.$type.'">' . $type . '';
  3. foreach ($property as $oneProperty) {
  4. foreach($oneProperty as $p)
  5. echo '<div style="margin:5px 0 0 5px;">' . $p . '</div>';
  6.  
  7. }
  8. echo '</div>';
  9. }
Oczywiście to jeszcze wersja robocza bo np style= zostanie usunięte itd.
nospor
Ciagle mowisz o przejsciu na obiektowek, dobrych praktykach itp a jak patrze na twoj kod to mnie przerazenie bierze. Balagan, nazewnictwo zmiennych z 4 liter i wszedzie panujacy chaos. Zamiast brac sie za obiektowke naprawde warto by poprawic te mase drobnych rzeczy, ktore kola oczy.

np te nieszczesne nazwy zmiennych, ktore totalnie nic nie mowia ala
$newProperty = $row['type'];

pobierasz typ a nazywasz go newProperty. Co ma typ do newPRoperty? No nic

$type = $row['type'];
Prawda ze czytelniej?

Albo tu:
foreach ($properties->groupFullProperties() as $type => $property) {
Przeciez tam jest kilka properties a nie jedna property wiec tak ma sie nazywac
foreach ($properties->groupFullProperties() as $type => $properties) {

Moze ci sie to wydawac smieszne takei czepiaanie, ale przy wiekszym kodzie ty naprawde sie nie polapiesz co jest co, nie wpsonijac o innej biednej osobie majacej pracowac na twoim kodzie.

Sorki, musialem, moze dotrze wink.gif

Wracajac do tematu: po co petla jeszcze na wyswietlanie description lang i property? Te wartosci znasz, petla jest totalnie zbedne i komplikuje zycie. Petle sie robi dla wartosci dynamicznych a nie stalych

  1. foreach ($properties->groupFullProperties() as $type => $properties) {
  2. echo '<div style="border:1px solid red; margin:5px 0 0 5px;" class="dynamicFields" id="'.$type.'">' . $type . '';
  3. foreach ($properties as $propertyData) {
  4. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['property'] . '</div>';
  5. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['label'] . '</div>';
  6. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['description'] . '</div>';
  7.  
  8. }
  9. echo '</div>';
  10. }

Czyz nie wyglada to czytelniej?


Teraz jak kod wyglada w miare ok, to mozna przejsc do problemu

  1. foreach ($properties->groupFullProperties() as $type => $properties) {
  2. echo '<div style="border:1px solid red; margin:5px 0 0 5px;" class="dynamicFields" id="'.$type.'">' . $type . '';
  3. foreach ($properties as $index => $propertyData) {
  4. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['property'] . '</div>';
  5. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['label'] . '</div>';
  6. if ($type !== 'Furniture' || $index === count($properties) - 1) {
  7. echo '<div style="margin:5px 0 0 5px;">' . $propertyData['description'] . '</div>';
  8. }
  9.  
  10. }
  11. echo '</div>';
sadistic_son
Cytat(nospor @ 4.01.2023, 11:48:13 ) *
nazewnictwo zmiennych z 4 liter
Wiem, nad tym muszę popracować. Czasem wymyślenie sensownej nazwy zmiennej zajmuje mi za dużo czasu, więc walę $p= i tyle. wiem, że to zły nawyk, muszę się go pozbyć.

Cytat(nospor @ 4.01.2023, 11:48:13 ) *
i wszedzie panujacy chaos.
Ale jak to? Kod ogólnie poformatowany, odstępy, wcięcia porobione. Co do mieszania php z html to wiem, że tak nie powinno się robić, ale w takiej sytuacji jak tutaj opisuję, to ta pętla powinna być w funkcji w pliku z klasą i tylko wklejone wywołanie metody wklejam to pliku z html?


Cytat(nospor @ 4.01.2023, 11:48:13 ) *
Moze ci sie to wydawac smieszne takei czepiaanie, ale przy wiekszym kodzie ty naprawde sie nie polapiesz co jest co, nie wpsonijac o innej biednej osobie majacej pracowac na twoim kodzie.

Absolutnie nie wydaje mi się to śmieszne. Lata pisania kodu tylko dla siebie (nigdy komercyjnie lub za drobne kwoty dla znajomych) spowodowały u mnie wyrobienie złych nawyków, z których mogę sobie nawet nie zdawać sprawy, lub ciężko mi się ich pozbyć. Staram się zacząć stosować PSR-12 ale do sukcesu jeszcze droga.


Cytat(nospor @ 4.01.2023, 11:48:13 ) *
Wracajac do tematu: po co petla jeszcze na wyswietlanie description lang i property? Te wartosci znasz, petla jest totalnie zbedne i komplikuje zycie. Petle sie robi dla wartosci dynamicznych a nie stalych
A no racja. Działa elegancko. Teraz muszę to ubrać w formularz, inputy, style itd.
Następnie zabieram się za problem z grupowania z tego nowszego tematu - 3 tabele, w tym łącznikowa.

Dzięki wielkie!!!!!
nospor
Cytat
Ale jak to? Kod ogólnie poformatowany, odstępy, wcięcia porobione. Co do mieszania php z html to wiem, że tak nie powinno się robić, ale w takiej sytuacji jak tutaj opisuję, to ta pętla powinna być w funkcji w pliku z klasą i tylko wklejone wywołanie metody wklejam to pliku z html?

Nazewnictwo z 4liter wproadza dla mnie wystarczajacy balagan wink.gif
Brak typowania
Do tego w html uzywanie inline STYLE zamiast klass i CSS dopelnia robote.

Cytat
Następnie zabieram się za problem z grupowania z tego nowszego tematu - 3 tabele, w tym łącznikowa.

Na stronie z grupowaniem, do ktorej odeslalem cie wczesniej, masz rozwiazanie z grupowaniem w bazie, przy pomocy GROUP BY i GROUP_CONCAT. Moze to byc bardziej przydatne. Wszystko zalezy co i jak bedzesz chcial wyswietlac

Cytat
to ta pętla powinna być w funkcji w pliku z klasą i tylko wklejone wywołanie metody wklejam to pliku z html?

Nie. Klasy nie powinny generowac zadnego kodu html.Do kodu html powinno uzywac sie widoku. Moze to byc zwykly plik .phtml czy tam nawet php a nie zadna klasa. Chodzi o rozdzielenie logiki od wyswietlania.
W mojej stopce masz link do Widoku takiego naprawde banalnego. Jakby cie interesowal cos powazniejszego to np. Twig
sadistic_son
Nazewnictwo zmiennych - ok, przyjąłem i się z tym nie kłócę smile.gif To trzeba usprawnić

Brak typowania - rozwiń trochę myśl pls.

Cytat(nospor @ 4.01.2023, 12:14:29 ) *
Do tego w html uzywanie inline STYLE zamiast klass i CSS dopelnia robote.
Tak robię tylko roboczo, jak potrzebuję zobaczyć na szybko co się wyświetla, to daję style="border:1px solid red; i widzę. Potem usuwał style= z html i wszystkie style wędrują do css/style.css


Cytat(nospor @ 4.01.2023, 12:14:29 ) *
Nie. Klasy nie powinny generowac zadnego kodu html. Do kodu html powinno uzywac sie widoku. Moze to byc zwykly plik .phtml czy tam nawet php a nie zadna klasa. Chodzi o rozdzielenie logiki od wyswietlania.
W mojej stopce masz link do Widoku takiego naprawde banalnego. Jakby cie interesowal cos powazniejszego to np. Twig
Ok, to rozumiem - mam oddzielne pliki do klas i oddzielne do widoku (czasem *.html a czasem *.php jak ten omawiany powyżej).
W moim zadaniu mam narzucone OOP i powiedziane, że programowanie proceduralne może być stosowane jedynie do zainicjowania klas PHP, a reszta logiki powinna być umieszczona wewnątrz metod klas. Stąd moje wcześniejsze pytanie o to czy ten foreach powinien powędrować do klasy. Jak rozumiesz w takim razie powyższy wytłuszczony fragment? Czy nie doczepią mi się, że zastosowałem programowanie proceduralne w pliku widoku?


Cytat(nospor @ 4.01.2023, 12:14:29 ) *
W mojej stopce masz link do Widoku takiego naprawde banalnego.
Wybacz pytanie, ale to artykuł z 2013. Czy te praktyki nadal obowiązuję w niezmiennej formie?
nospor
Cytat
Brak typowania - rozwiń trochę myśl pls.

Kazda metoda ma parametry i cos zwraca. parametry maja miec ustawiony typ, tak samo jak metoda ma miec ustawione co zwraca np twoja metoda:

public function groupFullProperties()
{
...
}

Ona zwraca tablice wiec masz to powiedziec w definicji

public function groupFullProperties(): array
{
...
}

Jakbys mial metode z parametrami to tez masz powiedziec jakiego typu jest dany parametr.
public function someMethod(int $number, string $name): array
{
...
}


Do tego byles odsylany pare tematow temu

Cytat
Ok, to rozumiem - mam oddzielne pliki do klas i oddzielne do widoku (czasem *.html a czasem *.php jak ten omawiany powyżej).

Na poczatek powinno wystarczyc

Cytat
W moim zadaniu mam narzucone OOP i powiedziane, że programowanie proceduralne może być stosowane jedynie do zainicjowania klas PHP, a reszta logiki powinna być umieszczona wewnątrz metod klas. Stąd moje wcześniejsze pytanie o to czy ten foreach powinien powędrować do klasy. Jak rozumiesz w takim razie powyższy wytłuszczony fragment? Czy nie doczepią mi się, że zastosowałem programowanie proceduralne w pliku widoku?

No jesli ktos ci kaze widok generowac w klasie to tak srednio na jeza ma pojecie. Wiec zakladam ze twoj zleceniodawca ma jednak pojecie i robienie widokow w oddzielnych plikach .php bedzie dla niego ok wink.gif

Cytat
Wybacz pytanie, ale to artykuł z 2013. Czy te praktyki nadal obowiązuję w niezmiennej formie?
Pytanie jak najbardziej zasadne. Klase te pisalem na php5 wiec jest daleka od poprawnych klas pisanych teraz w php8. Nie mniej jednak idea sie nie zmienila za bardzo a mi bardziej chodzilo o pokazanie idei a nie klasy wink.gif
sadistic_son
Super. Dzięki thumbsupsmileyanim.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.