Diskuze: Prázdná proměnná - jak jí eliminovat
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Jan Lupčík:18.12.2016 9:48
Při sečtení té proměnné dej vždy:
if (isset($promenna['qA1_1'])) { ... }
Nebo si vypni zobrazování Notice.
petr.jouza:18.12.2016 9:49
Ahoj,
proměnná musí mít vždy nějakou hodnotu a pokud ji máš někde
deklarovanou, musí se vyskytnout.
Udělej si tedy pomoví if a else nějakou kontrolu.
Třeba:
<?php
if (isset($_POST['qA1_1'])) {$qA1_1 = $_POST['qA1_1'] ;} esle {$qA1_1 = 0 ;}
?>
Pak se tedy ta proměnná vyskytne a nebude ti hlásit undefined index.
Tady je můj zdroják. Chci mít následující podmínku: Pokud proměnná $qA01_1 je rovna hodnotě "A" pak nabude hodnoty 3, pokud bude jakákoliv jiná hodnota, nebo bude proměnná prázdná, pak bude hodnota proměnné rovna 0. Nějak mi to ale s tou prázdnou proměnnou nefunguje.
//1.1
if($qA01_1 =="A")
{$qA01_1 = 3;}
elseif(empty($qA01_1))
{$qA01_1 = 0;}
else
{$qA01_1 = 0;}
//1.2
if($qA01_2 =="A")
{$qA01_2 = 3;}
elseif(empty($qA01_2))
{$qA01_2 = 0;}
else
{$qA01_2 = 0;}
//1.3
if($qA01_3 =="A")
{$qA01_3 = 3;}
elseif(empty($qA01_3))
{$qA01_3 = 0;}
else
{$qA01_3 = 0;}
//1.4
if($qA01_4 =="A")
{$qA01_4 = 3;}
elseif(empty($qA01_4))
{$qA01_4 = 0;}
else
{$qA01_4 = 0;}
//1.5
if($qA01_5 =="A")
{$qA01_5 = 3;}
elseif(empty($qA01_5))
{$qA01_5 = 0;}
else
{$qA01_5 = 0;}
Michal:18.12.2016 13:46
Jednak doporučuji, aby si na takto velké množství proměnných používal pole. Je to přehlednější a pohodlnější.
Každopádně, pokud pracuješ s takto pevně pojmenovanými proměnnými:
$qA01_1
...
$qA01_5
$qA02_1
...
$qA10_5
můžeš je procházet cyklem i když v poli nejsou. Pokud jsem dobře pochopil tvůj problém, šel by vyřešit takto:
for($i = 1; $i <= 10; $i++) {
for($j = 1; $j <= 5; $j++) {
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j;
$$name = +(isset($$name) && $$name === 'A');
}
}
Ve zkratce to znamená, že se projdou všechny proměnné s názvem ve tvaru $qA[1-10]_[1-5]. Pokud proměnná neexistuje nebo neobsahuje hodnotu A, přepíše se na hodnotu 0, jinak bude obsahovat 1.
Oxtimus pochopil jsi to dobře,
děkuji za pomoc, ale pořád mi to háže hlášku "Undefined index". V celku
chápu první řádek tvého kódu, i dtuhý, u třetího si nejsem jistý co
dělá ten otazník, u čtvrtého řádku jsem docel ztracen. Uvádím zde
většinu mého zdrojáku, třeba bude chyba ještě někde jinde.
<?php
//Zadání proměnných
$qA01_1 = $_POST['qA01_1'];
$qA01_2 = $_POST['qA01_2'];
$qA01_3 = $_POST['qA01_3'];
$qA01_4 = $_POST['qA01_4'];
$qA01_5 = $_POST['qA01_5'];
$qA02_1 = $_POST['qA02_1'];
$qA02_2 = $_POST['qA02_2'];
$qA02_3 = $_POST['qA02_3'];
$qA02_4 = $_POST['qA02_4'];
$qA02_5 = $_POST['qA02_5'];
$qA03_1 = $_POST['qA03_1'];
$qA03_2 = $_POST['qA03_2'];
$qA03_3 = $_POST['qA03_3'];
$qA03_4 = $_POST['qA03_4'];
$qA03_5 = $_POST['qA03_5'];
$qA04_1 = $_POST['qA04_1'];
$qA04_2 = $_POST['qA04_2'];
$qA04_3 = $_POST['qA04_3'];
$qA04_4 = $_POST['qA04_4'];
$qA04_5 = $_POST['qA04_5'];
$qA05_1 = $_POST['qA05_1'];
$qA05_2 = $_POST['qA05_2'];
$qA05_3 = $_POST['qA05_3'];
$qA05_4 = $_POST['qA05_4'];
$qA05_5 = $_POST['qA05_5'];
$qA06_1 = $_POST['qA06_1'];
$qA06_2 = $_POST['qA06_2'];
$qA06_3 = $_POST['qA06_3'];
$qA06_4 = $_POST['qA06_4'];
$qA06_5 = $_POST['qA06_5'];
$qA07_1 = $_POST['qA07_1'];
$qA07_2 = $_POST['qA07_2'];
$qA07_3 = $_POST['qA07_3'];
$qA07_4 = $_POST['qA07_4'];
$qA07_5 = $_POST['qA07_5'];
$qA08_1 = $_POST['qA08_1'];
$qA08_2 = $_POST['qA08_2'];
$qA08_3 = $_POST['qA08_3'];
$qA08_4 = $_POST['qA08_4'];
$qA08_5 = $_POST['qA08_5'];
$qA09_1 = $_POST['qA09_1'];
$qA09_2 = $_POST['qA09_2'];
$qA09_3 = $_POST['qA09_3'];
$qA09_4 = $_POST['qA09_4'];
$qA09_5 = $_POST['qA09_5'];
$qA10_1 = $_POST['qA10_1'];
$qA10_2 = $_POST['qA10_2'];
$qA10_3 = $_POST['qA10_3'];
$qA10_4 = $_POST['qA10_4'];
$qA10_5 = $_POST['qA10_5'];
$empty=strlen($_POST['number']);
if ($empty==0)
{
die('Zadej.');
}
else
{
$R = $_POST['number'];
}
for($i = 1; $i <= 10; $i++) //interval 1 az 10, "$i++" je inkremnetace - promenna $i je v dalsim cyklu o +1 vyssi
{
for($j = 1; $j <= 5; $j++) { //interval 1 az 5, "$j++" inkremnetace - promenna $j je v dalsim cyklu o +1 vyssi
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j; // promenna $name je tvorena retezcem, "tecka" spojuje retezec, co dělá otazník?
$$name = +(isset($$name) && $$name === 'A');
}
}
$V= $qA01_1+ $qA01_2+ $qA01_3+ $qA01_4+ $qA01_5+ $qA02_1+ $qA02_2+ $qA02_3+ $qA02_4+ $qA02_5+ $qA03_1+ $qA03_2+ $qA03_3+ $qA03_4+ $qA03_5+ $qA04_1+ $qA04_2+ $qA04_3+ $qA04_4+ $qA04_5+ $qA05_1+ $qA05_2+ $qA05_3+ $qA05_4+ $qA05_5+ $qA06_1+ $qA06_2+ $qA06_3+ $qA06_4+ $qA06_5+ $qA07_1+ $qA07_2+ $qA07_3+ $qA07_4+ $qA07_5+ $qA08_1+ $qA08_2+ $qA08_3+ $qA08_4+ $qA08_5+ $qA09_1+ $qA09_2+ $qA09_3+ $qA09_4+ $qA09_5+ $qA10_1+ $qA10_2+ $qA10_3+ $qA10_4+ $qA10_5;
$A= ($V/$R)*100;
?>
Michal:19.12.2016 13:56
Otazník
Tzv. ternární operátor je zkrácenou obdobou podmínky. Má syntaxi
[podmínka] ? [pokud platí] : [pokud neplatí]. Níže
položené zápisy dělají to samé. Používám to proto, aby v názvu
proměnné bylo číslování jako 01, 02, ... a ne
1, 2, ...
// Ternární operátor
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j;
// Klasická podmínka
$name = 'qA';
if ($i < 10) {
$name .= '0' . $i; // Pokud je $i menší než 10, napíše se před něj 0.
} else {
$name .= $i;
}
$name .= '_' . $j;
Přepsání proměnné
Opět nejde o nic jiného, než o zkrácený zápis podmínky. Podmínkou
zjistíš, zda je proměnná definována a zároveň obsahuje A. Tím
dostaneš boolean, tedy pravdivostní hodnotu true nebo
false. Převedení na číslo 1 nebo 0 docílíš
znaménkem + před tím celým výrazem. Níže položené zápisy
opět dělají to samé.
// Zkrácený zápis
$$name = +(isset($$name) && $$name === 'A');
// Klasická podmínka
if (isset($$name) && $$name === 'A') {
$$name = 1; // Pokud proměnná existuje zároveň obsahuje A, uloží se sem 1.
} else {
$$name = 0; // Pokud proměnná neexistuje nebo obsahuje cokoliv jiného, než A, uloží se sem 0.
}
Undefined index
Tyto proměnné by už měly fungovat, ale hlásí ti to chybu kvůli
$_POST['number'] na tomto řádku:
$empty=strlen($_POST['number']);
Řešení
Jak už jsem psal, není třeba ty hodnoty z $_POST ukládat do
dalších proměnných a až ty proměnné sčítat. Můžeš cyklem projet
celé $_POST, což není nic jiného, než pole. A pak také, na konci
nemusíš zdlouhavě vypisovat všechny proměnné, aby si je sečetl. Sečtení
můžeš provádět taktéž v cyklu. Takže tvůj algoritmus by šel zapsat i
takto:
$v = 0; // Proměnná pro výsledný součet.
$r = isset($_POST['number']) ? $_POST['number'] : 1; // Pokud existuje $_POST['number'], $r bude mít hodnotu jako $_POST['number'], jinak se nastaví defaultní hodnota 1.
for($i = 1; $i <= 10; $i++) {
for($j = 1; $j <= 5; $j++) {
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j;
$v += +(isset($_POST[$name]) && $_POST[$name] === 'A'); // K celkovému součtu se připočte 1 pokud je $_POST[$name] definováno a obsahuje A.
}
}
$a = $r !== 0 ? ($v / $r) * 100 : 'Dělení nulou'; // $a se vypočítá jen tehdy, když $r nebude 0.
+20 Zkušeností
+2,50 Kč
David Hynek:19.12.2016 21:26
Možná hloupá otázka, ale o polích jsi slyšel? Pak stačí pole jen sečíst.
Zdenek:21.12.2016 12:20
Oxtimus děkuji,
funguje mi to a rovněž i tvůj výklad a popis je opravdu na učitelské
úrovni, klobouk dolů. Jen mám ještě dilema, jestli není lepší místo
hodnoty "A", která později nabývá hodnoty 1 rovnou dát natvrdo číslo?
Tzn., že např. $qA01_1 bude mít hodnotu 2 a např. $qA02_1 bude mít hodnotu
3, $qA03_1 bude mít třeba hodnotu 5 atp. . Dal by se stávající zdroják
nějak lehce upravit ?
Děkuji
Zdenek:21.12.2016 12:25
O polích jsem slyšel,
snažím se nejprve napsat kód sám a pak, podle času a zkušeností (spíše
Vaších) si s tím pohrát. Jsem začátečník a jsem rád, za každý
zajímavý postřeh.
Michal:21.12.2016 13:30
Nejsem si jistý, co přesně myslíš. Aby proměnná $qA01_1 obsahovala hodnotu $_POST['qA01_1'], a pokud by tato hodnota byla A, přepsala by se na 1? Pokud ano, vnitřek cyklů uprav na:
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j; // Název proměnné, se kterou se pracuje, např. qA01_4.
$$name = isset($_POST[$name]) ? $_POST[$name] : null; // Do proměnné, jejíž název je uložen v $name se zkopíruje obsah příslušného $_POST.
if ($$name === 'A') {
$$name = 1; // Pokud je hodnota nově vzniklé proměnné A, přepíše se na 1, jinak zůstane stejná.
}
Osobně by mě zajímalo zda má smysl tohle vůbec řešit jinak, než že si vypnout tyhle "chyby". V některých případech mi přijde, že to kod jen z nepřehlední. Ve většině případech to ničemu nevadí.
Jen můj názor, ale rád uvitám smyslu plnou odpověď z důvodem proč by se to mělo za každou cenu takto kontrolovat.
mkub:21.12.2016 20:31
v PHP to, ze nie je definovana hodnota v premennej nie je pokladane za chybu, preto je ta chybova hlaska E_notice pri pouziti neexistujucej premennej, resp. neexistujuceho indexu
mkub:21.12.2016 20:33
pouzivaj tlacitko </> na vlozenie kodu a ak mas vela premien s rovnakym
nazvom, len sa lisia cislom, tak je lepsie pouzivat na to pole
a s jednym polom sa ovela lepsie pracuje, nez so stovkami premien
Zdenek:22.12.2016 14:05
Oxtimus díky,
ale nějak jsem se do toho zamotal. Pořád mi to háže, že výsledek je 0 .
Přitom minimálně jedna proměnná z pole qA01_1 až qA10_5 nabývá přímo
hodnoty 3. Ostatní mají pak hodnotu A nebo žádnou hodnotu. Tady je zdroják
co jsem dle tebe upravil.
<?php
$v = 0; // Proměnná pro výsledný součet.
$r = isset($_POST['number']) ? $_POST['number'] : 1; .
for($i = 1; $i <= 10; $i++) {
for($j = 1; $j <= 5; $j++) {
$name = 'qA' . ($i < 10 ? '0' . $i : $i) . '_' . $j;
$$name = isset($_POST[$name]) ? $_POST[$name] : null;
if ($$name === 'A') {
$$name = 1; }
}
}
$a = $r !== 0 ? ($v / $r) * 100 : 'Dělení nulou';
?>
Rozhodl jsem, že bude asi jednodušší namísto hodnoty A, která později nabude hodnoty 1, použít přímo hodnoty číselné. Takže jednotlivé proměnné qA01_1 až qA10_5 budou mít přímo různou číselnou hodnotu(např. 2 nebo 3 nebo 4), namísto hodnoty A.
...
Zobrazeno 18 zpráv z 18.