| 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: 12 let
|
|||
0