Autor Zpráva
Nailen
Profil
Zdravím,

mám databázi států a měn. Chci přes funkci vypsat seznam států.
Funkce vypadá takto:

function currency_list()
  {
      global $mysqli,$db_table_prefix; 
      $stmt = $mysqli->prepare("SELECT country
      FROM ".$db_table_prefix."currency");
      $stmt->execute();
      $stmt->bind_result($currency);
      $stmt->fetch();
      $stmt->close();
      return ($currency);
  }

Když potom vyvolám výpis
print currency_list($currency[1]);

tak se mi vypíše první země. Když změním 1 za 2, tak se pořád vypisuje první země. Jak mám upravit funkci, aby výstup z funkce bylo pole se seznamem zemí?

Zkoušel jsem tam dát
return array($currency);
ale nepomohlo mi to.

Děkuji za radu.
Taps
Profil
Nailen:
Pokud mas vice zemi tak je nutne ve funkci pouzit cyklus while
Nailen
Profil
Taps:

Děkuji za nasměrování. Bohužel to potřebuji ještě asi trochu jinak. Dovysvětlím můj problém.

Funkci jsem upravil takto:

function currency_list()
{
   global $mysqli,$db_table_prefix; 
   $stmt = $mysqli->prepare("SELECT country
    FROM ".$db_table_prefix."currency_list");
    $stmt->execute();
    $stmt->bind_result($country); 
    while ($stmt->fetch()) 
    {
        printf ("%s\n", $country);
    }  
  $stmt->close();
}

Nechápu proč, ale vypisuje mi to všechny země + jednu zkratku měny viz přiložený obrázek.

Austrálie Čína Dánsko EMS Chorvatsko Japonsko Kanada Maďarsko Norsko Polsko Rumunsko Rusko Švédsko Švýcarsko Turecko USA Velká Británie AUD



Já bych potřeboval funkci modifikovat tak, aby jen nepředávala kompletní výpis názvů zemí, ale aby mi předávala pole a mohl jsem pak dál pracovat s každou položkou seznamu.

Děkuji za radu.
juriad
Profil
Já bych to udělal asi takto:
function currency_list($cache = TRUE)
{
  global $mysqli, $db_table_prefix; 
  static $currencies = NULL;
  if ($currencies === NULL || !$cache)
  {
    $currencies = array();
    $stmt = $mysqli->prepare("SELECT id, country, currency
    FROM " . $db_table_prefix . "currency_list");
    $stmt->execute();
    $stmt->bind_result($id, $country, $currency); 
    while ($stmt->fetch()) 
    {
      # Vyber si, co ti víc vyhovuje:
      $currencies[$id] = array('country' => $country, 'currency' => $currency);
      #$currencies[$country] = $currency;
    }  
    $stmt->close();
  }
  return $currencies;
}

Vratí to pole všech záznamů v databázi. Navíc si to ty hodnoty zapamatuje, takže při dalším zavolání už se databáze neptá (to lze ovlivnit parametrem funkce). Má to několik výhod:
* nemusíš se zabývat předáváním toho pole a dávat si pozor, abys funkci nevolal zbytečně opaovaně
* data v této tabulce se nemění a je jich málo, takže si je klidně můžeme všechna zapamatovat
Nailen
Profil
juriad:

Zdravím,
váš kód se mi líbí a věřím tomu, že mě zase posune dál ve znalostech. Děkuji

Mám s ním ale problém, který se mi nedaří vyřešit. Dostávám toto hlášení:

Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement in...

Pokoušel jsem se to odladit, že jsem doplnil řádek takto: $stmt->bind_result($id, $country, $currency);

Když pak si přímo ve funkci nechám vypsat toto: print ($currencies[$id]);

tak dostávám výpis pouze "Array" jak kdyby se nic nedoplnilo.

Neměl být příkaz execute ještě před bin_result?

Jak správně vypsat jednotlivé položky z proměnné $currencies?

Děkuji za radu.
juriad
Profil
Máš pravdu v obou případech:
* přidal jsem $id
* prohodil execute a bind_result

To je správně, že vypíše Array. Protože uvnitř pole $currencies jsou dvouprvková pole obsahující zemi a měnu. Při vývoji si vypisuj proměnné pomoci var_dump. Pak bys viděl, celý obsah pole $currencies.
Právě z důvodu, že nevím, jak tu funkci chceš používat, navrhuji i tu zakomentovanou alternativu.
Alphard
Profil
Jen tak pro informaci, v [#4] juriad je napsaná velmi konkrétní funkce na 21 řádků, s použitím např. dibi by to šlo (až na cache, nevím, jestli ji chcete) udělat takhle
function currency_list() {
  return dibi::select('id, country, currency')->from('currency')->fetchAssoc('id');
}
Divím se, že někoho baví pořád dokola psát ručně konstrukce pro práci s nepohodlnými nativními knihovnami :-)
1Pupik1989
Profil
Mysqli má metodu fetch_all.
Nailen
Profil
Alphard:

Dobrý den,
omlouvám se za pozdní reakci. Váš zápis vypadá jednoduše. Předpokládám, že k tomu budu potřebovat ještě další znalosti a kód, aby tato funkce fungovala. Je to tak?

aktuálně mi to píše chybu: Class 'dibi' not found in...

Děkuji za odpověď.
xaverista
Profil
Nailen:
Ano, budete potřebovat knihovnu dibi
Na toto si tuším říct že stačí základní znalost OOP
Nailen
Profil
xaverista:

Dobrý den,

jsem laik a ve volném čase se bavím programováním. Pokud bych OOP měl, tak bych se nejspíš tady neptal na pro vás triviální dotazy.

Další můj dotaz zní: pokud si vypíši php info a dibi knihovnu ne webhostingovém serveru nemohu najít, tak ji můj poskytovatel nepodporuje? Je to tak, že by to musel doinstalovat správce hostingu, nebo to mohu nějak ovlivnit?

Děkuji za odpověď.


juriad:

Dobrý den,

vámi navržené řešení mi vypisuje toto: array(2) { ["country"]=> string(10) "Austrálie" ["currency"]=> string(3) "AUD" },...

Ano, budu potřebovat proměnou s dvouprvkovým polem s tím rozdílem, že tam budu mít zemi a id. V tom problém není. To jsem tam změnil.

Když dám výpis var_dump tak dostanu tento výpis: array(2) { ["country"]=> string(10) "Austrálie" ["id"]=> int(1) },...

Jestli jsem to dobře pochopil, tak funkce bude předávat v proměnné $currencies toto pole. Jak potom mohu přistoupit k jednotlivým datům této proměnné?
Děkuji

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: