PHP načítání obsahu souboru

HackForum

PHP načítání obsahu souboru #
Můžete mi prosím poradti s problémem v PHP.
Jde mi o toto:

Potřebuji udělat PHP script, který bude načítat jako hodnotu promněnné ($promena) různé řetězce umístěné POD SEBOU (!) v .txt souboru, který bude umístěn také na serveru.

Pro upřesnění: Mějme soubor pepa.txt, který obsahuje tyto řetězce:
jablko
ananas
auto
lyže
kolo

a PHP script: action.php
Od PHP scriptu chci aby převzal ze souboru pepa.txt hodnotu "jablko" - uložil ji do proměnné $promena - něco s proměnnou vykonal a vrátil se na začátek. Tentokrát by ze souboru pepa.txt převzal druhou hodnotu o řádek níž "ananas" , opět ji uložil do proměnné $promena, vykonal s ní to samé co s první proměnou a vrátil se opět na začáte...a to samé zopakoval třeba 100x...nakonec by narazil na prázdný řádek a tím by se ukončil...

Zkoušel jsem google, ale problém je, že sám nevím jak se zeptat.....je tento problém nějak snadno řešitelný nebo ne? Resp. napadají vás jiné způsoby ,. jak toho docílit (třeba to vůbec neřešit php..?)

Díky.



(odpovědět)
Miloš Zeman | 2001:41d0:52:300::*22.12.2013 13:39
re: PHP načítání obsahu souboru #
Ke čtení po řádcích slouží funkce fgets() ([link]). V kombinaci s cyklem foreach bys měl docílit přesně toho, co potřebuješ.
(odpovědět)
ScheRas | E-mail | Website22.12.2013 14:42
re: PHP načítání obsahu souboru #
[link]
Není to otestované, protože se mi nechtělo spouštět kvůli tomu Apache, ale takhle nějak by to šlo.

----------
Sec-Cave.cz - [link]
(odpovědět)
RubberDuck | E-mail | Website22.12.2013 14:59
re: PHP načítání obsahu souboru #
Řešení s file_get_contents() je špatně. Pokud bude mít ten soubor pár GB, je problém. PHP jak jistě víte limituje použitelnou paměť a vzhledem k tomu, že file_get_contents() načítá soubor celý, u větších souborů je to nepoužitelné.
O něco lepší je použití zmíněného fgets().

[link]

Jinak, chápu že je to jen example, ale ta kombinace file_get_contents() a $_GET je přesně ten důvod, proč máme tolik děravých webů.
(odpovědět)
mH~ | E-mail | Website22.12.2013 17:13
re: PHP načítání obsahu souboru #
Špatně to rozhodně není. To, že má někdo snahu zpracovat gigabajtový texťák PHPčkem je chyba.

To, že jsem neošetřil vstupy, je jasné. Šlo mu o kód, který zpracuje data, takže nepředpokládám, že by ho měl někde veřejně na webu.

A pokud tedy chceme slovíčkařit a býti hnidopichy, tvůj kód vyvolává Full Path Disclosure a řádek

echo mt_rand(0, 10000) . " {$radekSouboru}\n";

je špatně, protože do složených závorek se vkládají pro výpis pouze jednotlívé členy pole :)

Ale No flame. Taky beru, že jsi vytvořil jen example :)

----------
Sec-Cave.cz - [link]
(odpovědět)
RubberDuck | E-mail | Website22.12.2013 21:24
re: PHP načítání obsahu souboru #
Mě spíše přijde, že se chcete hádat.

Promiňte, ale nechápu, jak mě můžete upozorňovat na FPD, když ji Váš kód způsobuje taky. Samozřejmě, že nešlo o kompletní kód, stejně jako ten Váš. Každopádně na chyby typu file inclusion si myslím, že bylo na místě upozornit i u takového krátkého kódu, jako jste postoval. Na co by Vám jako útočníkovi bylo FPD v tomto případě netuším. Obzvlášť dnes, kdy většina rozumných hostingů provozuje produkční weby s vypnutným error_reportingem. To je snad základ.


Nesouhlasím s tím, že gigabajtový texťák je nutně chyba. Není to optimální, ale nevím, co by na něm mělo být špatného. Zase, nechápu proč se hádáte a předkládáte mi tu Váš osobní dojem k "(ne)správné velikosti texťáku". Pokud budete provozovat web se 100k hitů denně, jak často budete rotovat logy, aby jste v nich neměl nepořádek? Zase tak často ne. A věřte nebo ne, tyto logy potom také zabírají řádově gigabajty. Místo toho jste mi měl říct, proč podle Vás je použití file_get_contents() správně i u velkých souborů, což bylo téma na které jsem poukazoval.

Mimochodem, řekl jsem že fgets je "o něco lepší". Na opravdu velké balíky dat se používají generátory, ale tím jsem zadavateli dotazu nechtěl zatěžovat hlavu.

Omlouvám se, že jsem poukázal na něco, co mi přišlo nekorektní a mám-li tedy teď být také knidopich a slovíčkařit, můžete mi prosím ukázat zdroj, ze kterého jste načerpal informaci, že do složených závorek se vkládají pouze jednotlivé členy pole? (btw, tím jste myslel prvky pole, asi, že?)

Zmíněný zápis jsem použil protože mi osobně přijde přehlednější než

echo mt_rand(0, 10000) . " " . $radekSouboru;

Ale to už je jen moje osobní preference, stejně jako vy máte preference a zvyk, co se týče velikosti .txt souborů :) :P

Přeji pěkný den

(odpovědět)
mH~ | E-mail | Website22.12.2013 22:49
re: PHP načítání obsahu souboru #
Kdybych se chtěl opravdu hádat, hádal bych se. Pokud jde o funkci file_get_contents tak, jak jsem ji použil, opakuji znovu: Špatně to není. Můžeme tady polemizovat o vhodnosti té či oné funkce. Mohl jsem přímo odpovědět, že mezi nepovinné parametry funkce file_get_contents patří i offset a množství dat, které se má ze souboru načíst, ale proč bych to dělal, když jsem jasně řekl, že nemám zájem rozpoutávat nějaký flame? Nehledě na to, že cílem bylo napsat opravdu jednoduchý kód, který by tazatel pochopil a případně si jej doupravil k obrazu svému.

A jen pro upřesnění: Právě se zpracováváním velkých datových souborů mám reálné zkušenosti (řádově kolem 100GB na soubor), takže jsem měl možnost srovnávat různé přístupy a různé výsledky při použití různých programovacích jazyků.

Původně jsem se chtěl obsáhle vyjádřit i k dalším bodům. Nakonec jsem se ale rozhodl, že se rozepisovat nebudu, aby to nebylo chápáno jako útok. Takže jen krátce:

FPD - pro získání tvaru cesty ke kořenovému adresáři webu. Využitelnost je jasná hlavně na sdílených hostinzích.

Ad řádek kódu: Stačí odmazat složené závorky:
echo mt_rand(0, 10000) . "$radekSouboru";
a efekt je stejný. Co se zdrojů týká: Mám tady dvě starší knihy, kde se tohle rozebírá. Dalším místem, kde se tohle dosti intenzivně řešilo, byl blog Jakuba Vrány. Jinak: Já zápis se složenými závorkami používám rovněž - z důvodu přehlednosti.

Ad vypnutý error_reporting na rozumných hostinzích: No commet. Vím o tom své (to by pak těch slušných bylo asi jako prstů ruky) a Emkei by mi to potvrdil a přidal nepřeberné množství historek.

Abych to shrnul: Mým cílem rozhodně nebylo psát nějaký úžasný kód, ale dát tazateli rychlou odpověď a to jsem taky udělal. Vzhledem k tomu, jak tazatel položil otázku, mi bylo jasné, že se nebude jednat o velké soubory, a že si jednoduše můžu dovolit načíst celý obsah do paměti.

Pokud jsem se Vás jakkoliv dotknul, případně Vás přímo urazil, omlouvám se Vám.

Přeji pěkný den

----------
Sec-Cave.cz - [link]
(odpovědět)
RubberDuck | E-mail | Website23.12.2013 2:25
re: PHP načítání obsahu souboru #
Neomlouvejte se :D, rozhodně jste se mě nedotknul, spíše jsem měl pocit opačný. Jsem rád, že zde můžeme takto diskutovat a probrat některé věci více do hloubky, i když mírně offtopic. ;)

Řešil jste i načítání těch 100GB souborů v PHP? A řešil jste to pomocí file_get_contents? Rád bych se podíval na takové řešení.

Já netvrdím, že FPD není závažný bug. Tvrdím pouze to, že je to bug o mnoho méně závažný než L(R)FI. Je rozdíl, jestli 10 řádkový script zobrazí cestu nebo rovnou otevře dveře pro závažnější útok. Proto jsem na to upozornil. Toť vše. K výpisu chyb - to jestli někdo hostuje projekty na serverech které "vykecají" útočníkovi co se dá, nebo si to nevypne na vlastní VPSce je pouze jeho hloupost a je mi docela líto jejich zákazníků. Vždyť i na sdílených hostinzích jako je WEDOS se toho dá poměrně dost vypnout. Fakt je nejspíš ten, že hodně webů to má stále zapnuté a třeba zmíněný WEDOS tuším chyby zobrazuje defaultně. Já ale spíše narážím na servery, co mají vypisovaní chyb vypnuté.

Stále přesně nerozumím Vašemu výroku "je špatně, protože do složených závorek se vkládají pro výpis pouze jednotlívé členy pole". Co se týče mého zápisu, nevidím na něm nic špatného. Tak nevím. V ZEND PHP Coding Standarts ([link]) je to OK. Neměl by jste kdyžtak ty konkrétní odkazy do blogu pana Vrány? Nepodařilo se mi je vygúglovat. Celkem by mě ta diskuse zajímala, stále se je co učit :) Naučil jsem se tento zápis používat, protože mi přijde bezpečnější/přehlednější. Vypůjčím si jeden příklad z PHP.net


<?php
$juice = "apple";
echo "He drank some $juice juice.".PHP_EOL;
// Invalid. "s" is a valid character for a variable name, but the variable is $juice.
echo "He drank some juice made of $juices.";


versus


echo "He drank some juice made of {$juice}s.";



Omluvte mě, jestli mé příspěvky vyzněli nějak útočně, rozhodně jsem na Vás nechtěl nijak útočit. Jsem aktivním čtenářem Vašeho blogu a příspěvků na portálech o počítačové bezpečnosti a moje programátorské schopnosti zdaleka nedosahují těch Vašich. V rámci diskuze jsem chtěl poukázat na něco, co se mi nezdálo úplně dobré.

Díky za odpovědi :)
(odpovědět)
mH~ | E-mail | Website23.12.2013 8:22
re: PHP načítání obsahu souboru #
Díky za pomoc. S vaší pomocí jsem problém vyřešil.
Zde dávám hotový a odzkoušený kód (třeba se to někdy někomu hodí..)


<?php

$soubor = fopen("soubor.txt", "r");
$a = fgets($soubor);
$b = fgets($soubor);
$c = fgets($soubor);
$d = fgets($soubor);
$e = fgets($soubor);
$f = fgets($soubor);
$g = fgets($soubor);
$h = fgets($soubor);
$i = fgets($soubor);
$j = fgets($soubor);
$k = fgets($soubor);
fclose($soubor);


$promena= array ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k);
foreach ($promena as $hodnota)
{
echo $hodnota;
}

?>

Pro mé účely mi to zatím stačí takto, ale pokud někoho napadá, jak udělat kód, kdy nebudu muset vypisovat stovky či tisíce proměnných , ale "zacyklit to do jedné - $a), tak budu rád...:-)

(odpovědět)
Miloš Zeman | 46.227.171.*22.12.2013 21:53
re: PHP načítání obsahu souboru #
[link]

Měl jsem napsaný i popis toho co se děje na každém řádku, ale jelikož mě redakční systém na soom.cz odhlásil, tak z postu nezbylo nic.

Dodám jen, že rozhodně to nepraktikujte tak jak jste to napsal. Alokujete paměť pro každý řádek, to je špatně.
(odpovědět)
mH~ | E-mail | Website22.12.2013 23:09
re: PHP načítání obsahu souboru #
$soubor = fopen("soubor.txt", "r");
while(!feof($soubor))
{
$a = fgets($soubor);
echo $hodnota;
}
(odpovědět)
thecnology | 88.146.116.*22.12.2013 23:39
re: PHP načítání obsahu souboru #
to thecnology: Ještě jednou díky ! Po úpravě kód funguje přesně tak , jak jsem chtěl ...:-)


<?php

$soubor = fopen("soubor.txt", "r");
while(!feof($soubor))
{
$a = fgets($soubor);
echo $a;
}

?>

(odpovědět)
Miloš Zeman | 46.227.171.*23.12.2013 12:43
re: PHP načítání obsahu souboru #
To thecnology:
Díky za script.
V kódu ale není nikde přiřazena hodnota proměnné $hodnota, není ani zmínka že by si ji tahal z externího souboru.....$hodnota=$_GET["hodnota"];

Pls poraď...THX again :-)

(odpovědět)
Miloš Zeman | 46.227.171.*23.12.2013 11:27

Zpět
Svou ideální brigádu na léto najdete na webu Ideální brigáda
 
 
 

 
BBCode