Verze ke stažení
Yuhů vyzývá, abychom svůj web dali k dispozici ke stažení, v diskusi kdosi dokonce zmiňuje přímo PHP triky.
Když si chci nějaký web stáhnout, tak osobně používám wget, ale zrovna u tohoto webu to není právě jednoduché (protože obsahuje spoustu balastních odkazů kvůli reakcím na diskusní příspěvky pro uživatele s vypnutým JavaScriptem), takže verzi pro stažení dávám pokusně k dispozici.
Generuje se on-line, takže je vždy aktuální. K vytvoření archivu využívám knihovnu Archive_Tar, ale nejsem s ní příliš spokojen, protože data zapisuje do souboru a já bych je potřeboval dávat přímo na výstup. Také jsem zatím nerozchodil kompresi archivu, takže se data díky zlib.output_compression komprimují jen při přenosu.
Pro archiv platí stejné omezení jako pro web, tedy: Publikované texty můžete přetiskovat pouze se svolením autora. Ať vám tato verze slouží, připomínky uvítám v diskusi.
<?php include "./include/lib.inc.php"; include "./include/Tar.php"; header("Content-Type: application/x-tar"); register_shutdown_function(create_function('', 'unlink($GLOBALS["tempnam"]);')); $tempnam = tempnam($_ENV["TEMP"], "tar"); $tar = new Archive_Tar($tempnam); $tar->create(array("default.css", "favicon.ico", "logo.gif")); // články $archiv = ""; $result = mysql_query("SELECT *, UNIX_TIMESTAMP(publikovano) AS publikovano_ts FROM clanky WHERE publikovano <= CURDATE() ORDER BY publikovano DESC, id DESC"); while ($row = mysql_fetch_assoc($result)) { ob_start(); page_header($row["nadpis"]); echo $row["zprava"]; echo "<div class='podpis'>Jakub Vrána, " . date('j.n.Y', $row["publikovano_ts"]) . ", <a href='https://php.vrana.cz/$row[url].php'>on-line</a></div>\n"; page_footer(); $tar->addString("$row[url].html", ob_get_clean()); $archiv .= "<tr><td align='right'>" . date('j.n.Y', $row["publikovano_ts"]) . "</td><td><a href='$row[url].html'><strong>" . htmlspecialchars($row["nadpis"]) . "</strong></a></td><td><a href='https://php.vrana.cz/$row[url].php'>on-line</a></td></tr>\n"; } mysql_free_result($result); // archiv ob_start(); page_header(""); echo "<table cellspacing='0' cellpadding='3'>\n"; echo $archiv; echo "</table>\n"; page_footer(); $tar->addString("index.html", ob_get_clean()); $tar->_Archive_Tar(); header("Content-Length: " . filesize($tempnam)); readfile($tempnam); ?>
Diskuse
Jan Rozehnal:
Dobré. Nemohl byste uveřejnit kód který ten archív generuje?Tomik:
Také jsem čekal nějaký PHP trik, jak generovat z dynamických stránek, statický zabalený balíček... ;)Určitě bych ho uvítal...
Jakub Vrána
:
Vystavil jsem to. Není to žádný univerzální postup, ale je to ušité na míru tomuto webu. Stránky pro off-line stažení je stejně vhodné trochu upravit (nezobrazovat formulář pro vložení příspěvku do diskuse, nenabízet vyhledávání, nezobrazovat nejnovější články, ...).


Tomik:
Mnohokrát děkuji, jdu studovat... ;)Tibor:
PHP triky čítam už dlho a možnosť stiahnutia mi pomohla. Ďakujem.
Jakub Vrána
:
Zbavil jsem se závislosti na Archive_Tar a soubory nyní balím touto funkcí:
<?php
function tar_file($filename, $contents, $mtime)
{
$s = pack("a100a8a8a8a12a12", $filename, 0, 0, 0, decoct(strlen($contents)), decoct($mtime));
$checksum = 8*32; // space for checksum itself
for ($i=0; $i < strlen($s); $i++) {
$checksum += ord($s{$i});
}
$s .= sprintf("%06o", $checksum) . "\0 ";
$s .= str_repeat("\0", 512 - strlen($s));
$s .= $contents;
if (strlen($contents) % 512) {
$s .= str_repeat("\0", 512 - strlen($contents) % 512);
}
return $s;
}
// na konci vypsání patičky
echo pack("x512");
?>
Dodatečně mě napadlo, že místo vytváření dočasného souboru stačilo použít php://output, ale teď alespoň může být u souborů generovaných z databáze i správné datum vytvoření.


Pavel Z.:
Škoda, že tam také nejsou přibaleny komentáře. Vetšinou si v nich člověk celkem počte.
Jakub Vrána
:
OK, dal jsem to tam.


Jakub Vrána
:
Bohužel se mi nepodařilo rozchodit <?php fopen("compress.zlib://php://output", "wb"); ?> ani <?php gzopen("php://output", "wb"); ?>, takže jsem komprimaci nakonec vyřešil takto:
<?php
ini_set("zlib.output_compression", false);
$print = gzencode($print);
header("Content-Type: application/x-gzip-compressed");
header("Content-Length: " . strlen($print));
echo $print;
?>
Celý výstup se ukládá do proměnné a zkomprimuje se až na konci. Výhoda spočívá v tom, že je možné poslat velikost archivu, nevýhoda zase ve zbytečně veliké paměťové náročnosti.
Možná by bylo nejlepší data ukládat přeci jen do souboru, který by zároveň sloužil jako cache.


jonik555:
nešlo by udělat nějaký script, kterým by se dal stáhnout celý web-pokud není řešený přes DB?? samozřejmě jen někt. typy souborů

Jakub Vrána
:
Třeba takhle:
<?php
$zip = new ZipArchive;
$zip->open("web.zip", ZipArchive::OVERWRITE);
foreach (glob("*") as $filename) {
if (is_file($filename) && $filename != "web.zip") {
$zip->addFile($filename, $filename);
}
}
$zip->close();
header("Location: web.zip");
?>
Zamykání web.zip pro jednoduchost neřeším.


jonik:
a jak by to slo udelat na wz.cz? je tam akorat ZLIB a tohle tam bohuzel nefunguje...Dekuju
Michael Fanta:
Ahoj mohl by mi někdo poradit jak udělat to aby se mi na stránce ukázaly náhledy na všechny obrázky co obsahuje archiv ?
Jakub Vrána
:
<?php
define("SIRKA_NAHLEDU", 100);
define("VYSKA_NAHLEDU", 100);
$zip = new ZipArchive;
$zip->open($filename);
$sirka = ceil(sqrt($zip->numFiles));
$nahledy = imagecreatetruecolor(SIRKA_NAHLEDU * $sirka, VYSKA_NAHLEDU * ceil($zip->numFiles / $sirka));
for ($i=0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
$im = imagecreatefromjpeg("zip://" . dirname(__FILE__) . "/$filename#$stat[name]");
imagecopyresampled($nahledy, $im, SIRKA_NAHLEDU * ($i % $sirka), VYSKA_NAHLEDU * floor($i / $sirka), 0, 0, SIRKA_NAHLEDU, VYSKA_NAHLEDU, imagesx($im), imagesy($im));
imagedestroy($im);
}
?>
Předpokládá se, že všechny soubory v archivu jsou obrázky JPG. Vznikne jeden velký obrázek s náhledy, který lze zobrazit např. funkcí imagejpeg(). Tento obrázek je obvykle čtvercový, pokud bys preferoval pevnou šířku, stačí ji zadat do proměnné $sirka. Náhledy jsou zdeformované, to by se dalo vyřešit funkcí pro proporcionální zmenšení obrázků: http://php.vrana.cz/formaty-obrazku.php.


SodaE:
prosímtě Jakube kde seženu pesně tenhle class "ZipArchive" ?
Pavel:
Používám Vertrigo Server pod Windows a nevím, jak tam tu třídu ZipArchive zpřístupnit.Zkoušel jsem stáhnout php_zip.dll, přidat jej do složky ext a v php.ini připsat extension=php_zip.dll. Jenže to nepomohlo.
Co přesně je potřeba udělat? Díky komukoliv za případnou pomoc.
SodaE:
a bez modulu by to asi nešlo že :(
Diskuse je zrušena z důvodu spamu.

