IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Upload složky se zachováním její struktury (ssh2)

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Daniel Pitra
Člen
Avatar
Daniel Pitra:16.7.2020 12:00

Zdravím,

snažím se nastavit, aby se po vybrání souborů ve formuláři (viz níže) dala vybrat i celá složka, která by se nahrála se zachováním její struktury, ale zároveň se vynechaly všechny skryté (.*) soubory...

<form enctype="multipart/form-data" action="upload.php" method="post">
        <div class="card-body">
                <div class="form-group">
                        <label for="debFile">Deb file</label>
                        <div class="input-group">
                                <div class="custom-file">
                                        <input name="debFile" type="file" class="custom-file-input" id="debFile">
                                        <label class="custom-file-label" for="debFile">Choose .deb file</label>
                                </div>
                        </div>
                </div>
                <div class="form-group">
                        <label for="depicDir">Depiction folder</label>
                        <div class="input-group">
                                <div class="custom-file">
                                        <input name="depicDir[]" type="file" class="custom-file-input" id="depicDir" webkitdirectory multiple>
                                        <label class="custom-file-label" for="depicDir">Choose depiction folder</label>
                                </div>
                        </div>
                </div>
        </div>

        <div class="card-footer">
                <button name="upload" type="submit" class="btn btn-primary">Submit</button>
        </div>
</form>

Můj "upload.php" skript vypadá zatím takto:

<?php

require'../src/config-ssh.php';

$extra="new-package.php";

$deb_dir = "/var/www/html/debs/";
$depic_dir = "/var/www/html/depictions/";

if !empty($_FILES["debFile"]["name"]) {
        $deb_file = $deb_dir . basename($_FILES["debFile"]["name"]);
        $debFile = $_FILES["debFile"]["tmp_name"];

        if (ssh2_scp_send($ssh, $debFile, $deb_file, 0755)) {
                echo "DEB file ". basename( $_FILES["debFile"]["name"]). " has been uploaded.";
        }
}



preg_match('/(.*)_(.*)_/', $debFile, $display);
$dirname = $display[1];
$createDepicDir = $depic_dir . $dirname;
$createScreenshotDir = $createDepicDir . "/screenshots";

$sftp = ssh2_sftp($ssh);
if (ssh2_sftp_mkdir($sftp, $createDepicDir)) {
        echo "Depiction folder ". $dirname. " has been created.";
}
if (ssh2_sftp_mkdir($sftp, $createScreenshotDir)) {
        echo "Screenshots folder ". $createScreenshotDir. " has been created.";
}

$count = 0;

foreach (glob($_FILES['depicDir']['name']) as $i => $name) {
        if (strlen($_FILES['depicDir']['name'][$i]) > 1) {
                $depic_file = $depic_dir . basename($_FILES["depicDir"]["name"][$i]);
                $depicDir = $_FILES["depicDir"]["tmp_name"][$i];
                if (ssh2_scp_send($ssh, $depicDir, $depic_file, 0755)) {
                        $count++;
                }
        }
}


echo "<script>setTimeout(function(){location.href='".$extra."'} , 5000);</script>";
exit();

?>

Zkusil jsem: Nahrávání .deb souborů funguje bez problémů (pomocí ssh2_scp_send), ale stále zápasím s nahráním složky... Zkoušel jsem i ve skriptu nastavit, aby se nejdříve složky vytvořily, ale teď nevím, jak do nich ty soubory "nasměrovat".. Musí to být s použitím "ssh2", protože s použitím "move_uploaded_fi­le" bych musel pro obě složky (debs i depictions) nastavit oprávnění na 777, aby se do nich dalo skrz tento formulář nahrávat, a to z důvodu bezpečnosti nechci...

Chci docílit: Potřeboval bych, aby se .deb soubor nahrál do složky /debs (tohle mi funguje),
dále potřebuju, aby se vybraná složka s následující strukturou

"nějaká_složka"

  • info.xml
  • screenshots (složka)

-- 1.png
-- 2.png
-- i1.png
-- i2.png
atd.

... nahrála do složky /depictions a následně se ještě spustila série příkazů (ssh2_exec), nebo ideálně shell skript ("skript.sh")..

Předem díky za pomoc! ;-)

 
Odpovědět
16.7.2020 12:00
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:16.7.2020 20:27

Zkousel jsi to zazipovat?

 
Nahoru Odpovědět
16.7.2020 20:27
Avatar
Daniel Pitra
Člen
Avatar
Odpovídá na Peter Mlich
Daniel Pitra:16.7.2020 20:43

To vím, že by bylo možné, ale šlo mi o to, jestli existuje nějaká možnost, jak to udělat bez toho... Abych ušetřil co nejvíce kroků :D

Ale v případě zipu by se pak jak změnil ten skript? A šlo by to pak odzipovat přes ssh2?

Díky!

 
Nahoru Odpovědět
16.7.2020 20:43
Avatar
Jiří Havelka:16.7.2020 22:38

Jenom obecná poznámka rozhodně není pravda, že pro použití fce move_uploaded_file musíš nastavit oprávnění na 777. Je potřeba, aby ta složka byla čitelná pro uživatele, který spuští php (většinou www-data ve výchozím nastavení).
Ten zbytek asi takhe. Zamysli jestli opravdu potřebuješ to ssh pokud dobře chápu tak pracuješ v rámci jednoho stroja a využití ssh mi přijde divné.
Nesnažil bych se to rozbalovat pomocí php, ale pomocí bash scriptu (existuje pěkná utilitka unzip dostupná pro většinu linuksových distribucí). Ten bash script na rozbalení může při větším množství obrázků běžet docela dlouho, takže bych se možná vykašlal na pokusy spustit to přímo z php a místo toho bych to spustil třeba jako cron (pokud ti nevadí chvíli si počkat). Pokud by jsi chtěl uploadovat nezabalenou složku tak budeš muset vytvořit pro každý soubor všechny podsložky. Tím myslím toto vě složce budeš mít soubor a/b/d/neco.txt a budeš ho chtít umístít do složky /e/f/g/. Tak nejdřív musíš postupně vyvřit složky /e/f/g/a , /e/f/g/a/b , /e/f/g/a/b/d (pokud tyto složky již neexistují) a nakonec do složky /e/f/g/a/b/d/ nakopíruješ soubor neco.txt. V bashi by to šlo vyřešit jedním příkazem, ale v php asi budeš muset tohle udělat postupně pro všecny soubory a všechny podsložky.

 
Nahoru Odpovědět
16.7.2020 22:38
Avatar
Daniel Pitra
Člen
Avatar
Daniel Pitra:17.7.2020 21:44

Díky moc za pomoc! Nakonec jsem to vyřešil následovně:

<?php

require'../src/config-ssh.php';

$url="new-package.php";

$deb_dir = "/var/www/html/debs/";
$depic_dir = "/var/www/html/depictions/";

if (!empty($_FILES["debFile"]["name"])) {
        $debFile = $_FILES["debFile"]["tmp_name"];
        $deb_file = $deb_dir . basename($_FILES["debFile"]["name"]);

        if (!file_exists($deb_file)) {
                ssh2_scp_send($ssh, $debFile, $deb_file, 0755);
                echo nl2br ("DEB file ". basename( $_FILES["debFile"]["name"]). " has been uploaded.\n");
        } else {
                echo nl2br ("DEB file ". basename( $_FILES["debFile"]["name"]). " already exists!\n");
        }
}


if (!empty($_FILES["depicDir"]["name"])) {
        preg_match('/(.*)_(.*)_/', $_FILES["debFile"]["name"], $display);
        $dirname = $display[1];
        $createDepicDir = $depic_dir . $dirname;
        $createScreenshotDir = $createDepicDir . "/screenshots";
        $sftp = ssh2_sftp($ssh);

        if (ssh2_sftp_mkdir($sftp, $createDepicDir)) {
                echo nl2br ("Depiction folder ". $dirname. " has been created.\n");
        }
        if (ssh2_sftp_mkdir($sftp, $createScreenshotDir)) {
                echo nl2br ("Screenshots folder ". $createScreenshotDir. " has been created.\n");
        }

        foreach ($_FILES['depicDir']['name'] as $i => $name) {
                if (strlen($_FILES['depicDir']['name'][$i]) > 1) {
                        $depicDir = $_FILES["depicDir"]["tmp_name"][$i];
                        $info = getimagesize($_FILES['depicDir']['tmp_name'][$i]);
                        $depic_file = "$createDepicDir/" . basename($_FILES["depicDir"]["name"][$i]);
                        $screenshot_file = "$createScreenshotDir/" . basename($_FILES["depicDir"]["name"][$i]);

                        if (basename($_FILES["depicDir"]["name"][$i]) == "info.xml") {
                                ssh2_scp_send($ssh, $depicDir, $depic_file, 0755);
                                echo nl2br ("File ". basename( $_FILES["depicDir"]["name"][$i]). " has been uploaded.\n");
                        }
                        if ($info[2] === IMAGETYPE_PNG) {
                                ssh2_scp_send($ssh, $depicDir, $screenshot_file, 0755);
                                echo nl2br ("File ". basename( $_FILES["depicDir"]["name"][$i]). " has been uploaded.\n");
                        }
                }
        }
}

$stream = ssh2_exec($ssh, "/var/www/html/update.sh");
$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);

stream_set_blocking($errorStream, true);
stream_set_blocking($stream, true);

echo nl2br ("Output: " . stream_get_contents($stream));
echo nl2br ("Error: " . stream_get_contents($errorStream));

fclose($errorStream);
fclose($stream);


echo "<script>setTimeout(function(){location.href='".$url."'} , 5000);</script>";
exit();

?>

.. a vše funguje, jak má :)

 
Nahoru Odpovědět
17.7.2020 21:44
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:18.7.2020 19:36

Mno, mne prislo divne, ze by ti browser poskytoval celou strukturu na disku, ale asi jo, kdyz ti to funguje. Proto bych to zipoval. A zip stahnes jako cely soubor pres ssh a dal uz to rozbalujes beznymi prikazy nebo pres bash. Nebo, aspon tak si to myslim, nikdy jsem to nezkousel.
No, a tez, bezne se ssh pouziva jako vrstva nad tim, takze soubor dostava soubor ve files uz bez ssh. Takhle jsem to nikdy neresil, takze mi to prijde celkem zajimave tema.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
18.7.2020 19:36
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:18.7.2020 19:39

Jo, a jinak bych si na to udelal asi class nebo funkci nebo link na promenou, ktere predas obsah $FILES, abys to pak nemusel duplikovat a pri zmene jmena inputu pak cele prepisovat.

$dir_list = $_FILES["depicDir"];
$file_list = $_FILES["debFile"];
 
Nahoru Odpovědět
18.7.2020 19:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.