Autor Zpráva
Martin Adámek
Profil
Napadá někoho způsob, jak v php přes mysqli jednou ranou zjistit jednu potřebnou hodnotu?
(někdy 1 sloupec 1 řádku; někdy počet řádků z COUNT(*) )

V mysql jsem používal zápis
mysql_result(mysql_query("SELECT COUNT(*)...;"),0)
tedy de jure jeden příkaz, který šel použít klidně v podmínce nebo textovém řetězci (echo) bez přiřazování do proměnné a závěrečného středníku,
pokud jsem tu hodnotu už dál nepotřeboval.

V manuálu php, tady v diskusi, googlem i v článcích jsem hledal podobný procedurální zápis v mysqli, ale nenašel jsem.
Jako by nestačilo, že se musí pořád opakovat proměnná s připojením.
(OOP mi přijde být co do dýlky zdrojáku ještě horší; navíc už připojení k dbs mám procedurální, ne jako objekt.)

Chápu správně, že i u dotazu, kde dostanu jeden string nebo jeden int musím jít přes fetch_assoc a array, stejně jako u výsledků M řádků × N sloupců? Nejde to nějak ergonomičtějš?

Díky.
Keeehi
Profil
Něco takového by mohlo fungovat. Možná někde nějaká závorka kvůli prioritě.
$mysqli->query($query)->fetch_row()[0]
Martin Adámek
Profil
Bohužel mi nic na ten způsob nejde rozhejbat.
V rámci pokusů jsem dočasně zkusil i ubrat tu hranatou závorku a nechat si zatím celý pole
a závorky jsem zkoušel takhle:
print_r(($sql->query("SELECT CURDATE();"))->fetch_row());
a nefachá to.
Do prohlížeče to pošle úplně prázdnej výstup, tzn. asi syntaktická chyba (ani do error logu to nic nehodilo).

Pozitivní ale je, že jsem zjistil, že i když jsem se k dbs připojil postaru procedurálně,
tak ta proměnná s připojením se současně chová jako objekt, a objektový zápisy od ní obecně můžu chtít.
Taps
Profil
Mas chybne napsany sql dotaz. Fetch_row vybira jeden konkretni radek z toho duvodu je v hranate zavorce uvedeno cislo radku
Martin Adámek
Profil
Já jsem to teda chápal tak, že fetch_row načte první řádek, kterej je na řadě;
a hranatá závorka že z něj pak vytáhne sloupec, už jako z pole.

Nicméně, i když jsem zkusil
print_r(($sql->query("SELECT CURDATE();"))->fetch_row()[0]);
, tak se to chová pořád stejně.
Taps
Profil
A kdyz zadas
Select * from nazev_tabulky
Tak to taky nefunguje?
Keeehi
Profil
var_dump($sql->query("SELECT CURDATE();"));
Vypíše?
Martin Adámek
Profil
Keeehi:
Vypíše tohle:
object(mysqli_result)#2 (0) { } 
Martin2
Profil *
Martin Adámek:
Pořiď si debugger a proklikej si hodnoty proměnných, tohle hádání nikam nevede. Informace, že něco nefachá, je nám k ničemu. Samostatné prostudování objektu mysqli_result by pro tebe taky neměl být větší problém.

Keeehiho [#2] postup je funkční s malou poznámkou – přímá dereference pole vráceného z funkce jde až od PHP 5.4. Pokud máš nějakou prehistorickou verzi PHP, tak tady může být problém.
Martin Adámek
Profil
Martin2:
- ad debugger - Nehledám chybu v algoritmu; hledám obecné možnosti syntaxe.

- ad informace, že to nefachá, je ti k ničemu - hned za zásadní informaci, že to nefachá (tzn. že "tudy cesta taky nevede")
jsem napsal konkrétní projev, a to vč. explicitní informace, že do error logu to nehodilo nic a vlastního závěru, že jde o syntaktickou chybu; nevím, co bys chtěl víc.

- zkoušel jsem různé možnosti, vč. procedurálních ekvivalentů metod třídy mysqli_result,
nefachalo to (každý jinak, takže neuvádím detaily nefachání), nevygooglil jsem ani použitelný příklad, a tak jsem se tu zeptal... (jak jsem nastínil hned v prvním příspěvku)

- teoreticky by to mohlo být tou verzí, protože mám starší, ale jak jsem psal [#3] , zkoušel jsem použít i celý řádek výsledku dotazu, tzn. bez hranatých závorek,
tzn. pole jsem nerozebíral, a stejně to nefachalo (s uvedením přesného způsobu nefachání přímo tam, co jsem to psal [#3])
Martin2
Profil *
Martin Adámek:
do error logu to nehodilo nic a vlastního závěru, že jde o syntaktickou chybu
Jakákoliv chyba (mimo logické) končí chybovou hláškou. Jak zobrazit chyby PHP (nebo MySQL) si najdi sám.
Martin Adámek
Profil
Martin2:
Mám povolené E_ALL (a zrovna dneska jsem si ještě navíc přes OR přidal E_STRICT, bo v mé verzi PHP nejsou v E_ALL zahrnuty),
standardně mi chyby chodí do logu, občas si je zapnu do výstupu na web,
ale občas hezká syntaktická chyba způsobí, že nedostanu chybovou hlášku žádnou.
Většinou nějaká nejbanálnější (cca typu chybějící uvozovka, středník, apod.).
Ale nemám potřebu se tu s tebou hádat, ani rozvíjet offtopic.

Nicméně, rád bych nenápadně připomněl, že toto vlákno má za cíl nalézt mysqli náhradu za
mysql_result(mysql_query("SELECT COUNT(*)...;"),0)
(a než mě zase odkážeš na nápovědu, tak radši rovnou předem odpovím, že v ní se píše, že ta fce přímou náhradu nemá, a přes co se dá obejít;
a že mi ta nápovědou doporučovaná cesta nevyhovuje a proč jsem napsal výše )
Martin2
Profil *
Martin Adámek:
ale občas hezká syntaktická chyba způsobí, že nedostanu chybovou hlášku žádnou.
Syntaktická chyba vyvolá chybu typu E_PARSE. Žádné jiné situace v tomto případě neexistují.

Většinou nějaká nejbanálnější (cca typu chybějící uvozovka, středník, apod.).
Nesmysl.

Nicméně, rád bych nenápadně připomněl, že toto vlákno má za cíl nalézt mysqli náhradu za mysql_result
Řešení už podal Keeehi [#2]

a zrovna dneska jsem si ještě navíc přes OR přidal E_STRICT, bo v mé verzi PHP nejsou v E_ALL zahrnuty
Takže používáš PHP 5.3 nebo starší, jehož podpora skončila před nejméně dvěma lety a většina současných aplikací s ním není kompatibilní. Nemá smysl ti radit, jelikož nemáš ani tolik snahy, aby sis pro vývoj pořídil aktuální prostředí.
Martin Adámek
Profil
Martin2:

Ad 3:
Psal jsi, ze pricinou nekompatibility uvedeneho reseni ma byt
přímá dereference pole vráceného z funkce
coz jsem psal, ze pricina neni, protoze mi to nejde ani bez hranaty zavorky, nedava mi to ani cely radek (cele pole).

Chybne nebo irelevantni vyroky 1,2,4 nebudu komentovat, bo to prokazatelne nema smysl.
Martin Adámek
Profil
Keeehi:
$mysqli->query($query)->fetch_row()[0]

Na PHP5.5 mi běží získání řádku:
print_r($sql->query("SELECT CURDATE();")->fetch_row());
mi vypíše:
Array ( [0] => 2016-07-23 )


Ale pokud jde o jednu hodnotu, to je horší:
Zápis
print_r(($sql->query("SELECT CURDATE();")->fetch_row())[0]);
(nebo totéž jako echo)
mi hodí úplně prázdnou stránku.

(a i přes to, jak zásadně mi Martin2 nevěří, musím trvat na tom, že ač mi server hlásí errory, warningy, noticy i stricty, tak v tomhle případě prostě nehlásí nic, jen hodí prázdnej výstup;
a kdo tomu nevěří, toho už evidentně neumím přesvědčit)


Napůl řešení:
Začet jsem se do array_* funkcí, a tohle mi funguje:
echo array_pop($sql->query("SELECT CURDATE();")->fetch_row());
Krásně vypíše:
2016-07-23 
Jenže bohužel taky:
PHP Strict Standards:  Only variables should be passed by reference

Sice je to jenom strict... ale když už něco dělám, tak radši pořádně.
Napadá někoho nějaká úprava, aby s tím byl server úplně spokojenej?
(Pro maximální minimalizaci rizika, že o pár verzí pozdějš bude tenhle zápis zakázanej)
Keeehi
Profil
Něco je na tom velmi divné. Fungovat by to mělo.
3v4l.org/dDlOV

Vždy si ještě můžeš udělat vlastní funkci
function mysqli_result($result , $row, $field = 0) {
    $result->data_seek($row);
    $row = $result->fetch_row();
    return $row[$field];
}
Je taková hodně jednoduchá, bez kontrol vstupů a rozsahu ale to snad zvládneš případně dodělat.
Alphard
Profil
Keeehi [#16] tady testuje ještě trochu jiný případ než [#15] Martin Adámek. V zápise
($sql->query("SELECT CURDATE();")->fetch_row())[0]
a
$mysqliResult->fetch_row()[0]
je pro PHP do verze 7 rozdíl, ten první končí syntaktickou chybou. PHP parser byl dost dobastlený pro konkrétní případy, v některých se choval dokonce chybně a každá závorka navíc to mohla rozbít. Od verze PHP 7, kdyby byl parser přepsán a byl zaveden Abstract Syntax Tree by oba zápisy měly být myslím ekvivalentní a funkční (detailně se to pitvalo v RFC, teď se mi to nechce hledat).

Martin Adámek:
Když uděláte jinou zřejmou syntaktickou chybu, vypíše se chybová hláška?

A malý tip na závěr, PHP nemá pohodlnou extenzi pro přístup k databázi, doporučuji používat databázové vrstvy třetích stran, třeba dibi, kde by stačilo zavolat:
$value = $result->fetchSingle();
pcmanik
Profil
Alphard:
PDO to má rovnako jednoduché, stačí použiť $result->fetchColumn();
Martin Adámek
Profil
Alphard, pcmanik:
Díky za tipy.

Osobně se mi asi nakonec nejvíc líbí cesta vlastní pomocné funkce, jak zmiňuje Keeehi.
Sestavím si ji sice jinak, podle své potřeby, ale ten princip bude pro mě asi to nejlepší, a zůstanu tak na klasickém mysqli.

Ostatně, své drobné fce mám i na výpis odkazu (vložení ikonky formátu, zjištění a výpis velikosti souboru u mě, vložení JS pro nový tab a ikonky u linku jinam...) a jiné drobnosti, tak si rád uzpůsobím i tohle.
Jen jsem chtěl mít jistotu, že to v rámci mysqli fakt nejde nativně, abych znova nevyráběl už existující (kdysi v začátcích jsem si vyrobil ekvivalent in_array, než jsem zjistil, že existuje nativně :) - tak jsem nechtěl spáchat něco podobného znova).

Alphard:
Když třeba vynechám středník, tak taky dostanu prázdnej výstup, a chybu to nehodí.
Asi to plyne z konfigurace hostingu, nebo nevím... Je fakt, že na jiném hostingu mi server chybějící středníky, uvozovky apod. hlásil, ale tenhle to prostě nedělá.
Upozorní mě warningem třeba na to, že jsem své vlastní fci dal málo parametrů; ale kde jsem fatálně zapomněl středník, to si musím najít sám.

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: