Autor | Zpráva | ||
---|---|---|---|
pavel_pokorny Profil |
#1 · Zasláno: 24. 2. 2014, 09:39:39
Mám problém s nahráním a výpočtem průměru ze souboru - soubor je číselný a řádek obsahuje vždy jen jedno libovolné číslo.
Jednou mi to prošlo a při načitání jiného souboru mi to vyhodilo chybu. píše mi to: Warning: file(text.txt): failed to open stream: No such file or directory ... on line 16 Warning: Division by zero in ... on line 27 Dále si nevím rady: Jak zkontrolovat zda se jedná v souboru jen o čísla? Při změně souboru se mi data neaktualizují? Kompletní script zde: <!DOCTYPE html> <?php // post file if(isset($_POST['submit'])) { $file = $_FILES['file']['name']; // posted file // parsing of file type $parse = explode('.',$file); $pripona = $parse['1']; if(empty($file)){ $_error = 'Chyba: Nenahráváte žádný soubor!'; } else { if($pripona == 'txt' or $pripona == 'csv') { $fp = file($file); //if(preg_match('/[0-9\s]+$/', $fr)) { $hodnota = array(); // define value for array // make an array from file for($i = 0; $i < count($fp); $i++) { echo $hodnota[] = $fp[$i]; } // filtering values $uprava = array_filter($hodnota, create_function('$hodnota','return preg_match("#\S#", $hodnota);')); $prumer = array_sum($hodnota)/count($uprava); /* } else { $_error = 'Chyba: Soubor neobsahuje jen čísla!'; } */ } else { $_error = 'Chyba: Nahráváte nepovolený formát souboru!'; } } } $page = '<html>'; $page .= '<head>'; $page .= '<meta charset="UTF-8">'; $page .= '<title>Úkol - Ing. Pavel Pokorný</title>'; $page .= '<link rel="stylesheet" type="text/css" href="css.css">'; $page .= '</head>'; $page .= '<body>'; // inputs files $page .= '<div id="results">'; if(!empty($_error)) { $page .= '<span>'.$_error.'</span>'; } if(!empty($prumer)){ $page .= '<b>Výsledek:</b><br> Aritmetický průměr je: <span>'.$prumer.'</span>'; } $page .= '</div>'; $page .= '<form action="" method="post" enctype="multipart/form-data">'; $page .= '<label for="file">Zvolte soubor:</label><input type="file" name="file" value="" id="file"><em>povolené formáty souboru jsou: .txt, .csv</em><br>'; $page .= '<input type="submit" name="submit" value="odeslat">'; $page .= '</form>'; $page .= '</body>'; $page .= '</html>'; echo $page; Děkuji moc za radu |
||
Alphard Profil |
#2 · Zasláno: 24. 2. 2014, 09:49:14
Tak si přečtěte ty chyby, co vám to píše. Zadaný soubor neexistuje, protože ho hledáte na špatném místě, správný název souboru po uploadu je v
$_FILES['file']['tmp_name'] .
Dělení nulou matematicky není definováno, takže si výpočet musíte ošetřit podmínkou tak, aby k němu nemohlo dojít. |
||
pavel_pokorny Profil |
já si je právě četl, jen mi nejde do hlavy, že jeden soubor formátu .txt mi projde i s $_FILLES['file']['name'] v pohodě a spočítá se. Drůhý s podobnými čísly mi vyhazuje chybu. Dělení nulou tam být nemůže, jelikož soubory jsou nenulové.
Testoval jsem to na 'tmp_name', ale to mi nepomůže, potřebuju, aby se soubory nahrávaly jen z toho inputu. I tak děkuji za radu. |
||
Alphard Profil |
#4 · Zasláno: 24. 2. 2014, 10:21:10
Asi už existuje. Neřešte případy, které fungují náhodou :-) a znovu si přečtěte, pod jakým klíčem máte hledat uploadovaný soubor.
|
||
Tori Profil |
pavel_pokorny:
„Dělení nulou tam být nemůže, jelikož soubory jsou nenulové.“ Soubor může obsahovat cokoliv, ale když máte špatnou cestu k souboru, tak vám file na ř.16 vrátí false, cyklus for se neprovede, v $hodnota zůstane prázdné pole, a nakonec dělíte nulu nulou.
„Jak zkontrolovat zda se jedná v souboru jen o čísla? “ Pouze celá čísla, bez mezer okolo: return preg_match("#^\d+$#", $hodnota);
Ale dalo by se použít i tohle: array_filter($hodnota, 'intval'); - nečíselné položky to vyháže, ale na druhou stranu tam projde exponenciální zápis čísel (1e5 ), záleží na vás, jestli ho chcete povolit. array_sum v podstatě všechny nečíselné položky přetypovává na čísla, 1e2 připočítá správně, takže pokud byste nepotřeboval upozorňovat na chybný formát souboru, tak tam ř.26 ani být nemusí.
K volání file bych přidala flag FILE_IGNORE_NEW_LINES , ať vám nenechává zalomení řádku u každého čísla.
|
||
pavel_pokorny Profil |
v zadání mohou být jen celá čísla s bílými znaky okolo, upravil jsem to takto, průmery to počítá.
Jen nevím jak zajistit, aby se v případě jiného znaku než čísla a whitespace vyhodila chyba // post file if(isset($_POST['submit']) && !empty($_FILES['file']['name'])) { $file = $_FILES['file']['name']; // parse file $parse = explode('.', $file); $pripona = $parse[1]; // must be file .txt or .csv if($pripona == 'txt' or $pripona == 'csv') { $file_tmp = $_FILES['file']['tmp_name']; // file open $fileOpen = file($file_tmp); $hodnota = array(); for($i=0; $i < count($fileOpen); $i++) { $hodnota[] = $fileOpen[$i]; } // filtering values $uprava = array_filter($hodnota, create_function('$hodnota','return preg_match("#\S#", $hodnota);')); $prumer = array_sum($hodnota)/count($uprava); } else { $_error = 'Chyba: Nahráváte nepovolený formát souboru!'; } } else { $_error = 'Chyba: Nenahráváte žádný soubor!'; } |
||
Tori Profil |
#7 · Zasláno: 24. 2. 2014, 11:43:26
Porovnejte počet položek v polích $hodnota a $uprava, pokud se liší, tak některá položka nevyhovovala.
|
||
pavel_pokorny Profil |
#8 · Zasláno: 24. 2. 2014, 11:48:58
to jde, ale moho tam byt i prázdné řádky, tak to by mi porovnání házelo chybu
|
||
Chro Profil |
#9 · Zasláno: 24. 2. 2014, 11:55:11
Jestli ti mohu poradit v jiné věci a to kontrole povolených přípon souboru. Nejprve kontroluj, zda název souboru obsahuje tečku, třeba funkcemi strpos nebo substr_count. Pokud ano, rozděl název souboru podle tečky funkcí explode do pole, vytáhni poslední položku funkcí end a tu dále porovnávej. Zamezíš tak problému, pokud bude název souboru tř. data.od.pepy.csv
|
||
Tori Profil |
pavel_pokorny:
„moho tam byt i prázdné řádky“ , ale nemusejí: $fileOpen = file($file_tmp, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
|
||
peta Profil |
#11 · Zasláno: 24. 2. 2014, 12:20:33
Chro:
"třeba funkcemi strpos" Neni lepsi strrpos? Zrovna ziskas pozici tecky pocitanou od konce, pak pouzijes substr a nemusis nic explodovat. |
||
Chro Profil |
#12 · Zasláno: 24. 2. 2014, 12:28:56
peta:
To je samozřejmě také platný postup. Možná o něco rychlejší, možná s o jednou funkcí méně... Použil jsem ten, který mi vyhovoval v jednom ze skriptů. Potřeboval jsem totiž kontrolovat i možnou "předpříponu" uploadovaného souboru, př. soubor.jpg.zip. |
||
pavel_pokorny Profil |
#13 · Zasláno: 24. 2. 2014, 12:33:10
upravil jsem to parsovani
// parse file $pozice = strrpos($file, '.'); $pozice = $pozice-1; $pripona = substr($file, '-'.$pozice); ale porář mi to bere v potaz i jine znaky než čísla, potřebuju, aby se v případě jiného znaku než čísla vyhodila chyba |
||
Chro Profil |
#14 · Zasláno: 24. 2. 2014, 12:44:34
Pro kontrolu, zda je řetězec složen jen z číslic, lze použít funkci ctype_digit(), která vrací TRUE/FALSE.
|
||
pavel_pokorny Profil |
ctype_digit nezabralo, vrací to pokaždé chybu, nešlo by to nějak třeba přes preg_match?
if(ctype_digit($hodnota) == true) { // filtering values $uprava = array_filter($hodnota, create_function('$hodnota','return preg_match("#\S#", $hodnota);')); $prumer = array_sum($hodnota)/count($uprava); } else { echo = 'chyba'; } |
||
peta Profil |
Slo, sak si to najdi v dokumentaci mezi priklady nebo na regexp.
Tezko rici, proc ti to nefunguje, kdyz jsi nedal seznam vstupnich hodnot pro $hodnota do scriptu (schazi tam radek $hodnota = 'neco';). http://cz1.php.net/preg_match http://www.regexp.cz/ - [:digit:] http://cz1.php.net/ctype_digit - mi prijdou example 1 a 2 jasne a vypadaji funkcne, netestoval jsem |
||
pavel_pokorny Profil |
#17 · Zasláno: 24. 2. 2014, 14:15:12
seznam vstupních hodnot
$hodnota = array('6', '-66', 'ahoj', '66', '6'); potřebuju z toho průměr tedy ať bere i záporná čísla |
||
Alphard Profil |
#18 · Zasláno: 24. 2. 2014, 15:45:55
$hodnota = array_filter($hodnota, function($v) { return is_numeric($v); } ); |
||
pavel_pokorny Profil |
#19 · Zasláno: 24. 2. 2014, 15:52:22
povedlo se, funguje jak má
Děkuji všem moc za rady |
||
Časová prodleva: 10 let
|
0