« 1 2
Autor Zpráva
Tomáš123
Profil
juriad:
Tady jsi měl jiné uzávorkování.
Prišiel som na to okamžite po odoslaní :-), preto som to aj vymazal.

Dodám snad funkční kód
Neviem, či je kód funkčný, ale ja ho nemôžem použiť. Cením si tvoju snahu, ale kód je na mňa priveľmi zložitý. S mojimi aktuálnymi vedomosťami by som nikdy nič podobné nevymyslel. Ako ho budem upravovať? Stále písať sem na diskusiu? Ospravedlňujem sa, ale musíš so mnou pomaly.

už jsme tě nechali trápit dost dlouho
Ja sa netrápim, ale učím, nie je to moja vypočítavosť písať sem čo najviac, aby mi niekto napísal kód, dokonca ja cudzí kód ani nechcem. Takisto by pre teba bolo vyčerpávajúce všetko mi vysvetliť. :-)

Ale každopádne, veľmi si cením tvoju snahu. Ďakujem :-)

Momentálne mám tento kód:
<?php
    if (isset($_GET['page'], $_GET['article'])) {
        $url = $_GET['page'].$_GET['article'];
    }
    else {
        include 'includes/index.php';
    }
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="css/default.css">
        <title>
            <?php echo $title;?>
        </title>
    </head>
    <body>
        <?php
            if ($url = "blog1")
                include 'includes/blog/article-1.php';
            if ($url = "blog2")  //Ak tu použijem elseif, nenačíta sa žiadny súbor
                include 'includes/blog/article-2.php';
            else 
                include 'includes/blog/index.php';            
        ?>
    </body>
</html>
Avšak súbory sa includujú stále a všetky, bez ohľadu na URL... Čo je tam zlé?
lionel messi
Profil
Tomáš123:
Čo je tam zlé?
Prvá a základná chyba (môže ich tam byť aj viac, tiež som len amatér): Operátor porovnávania (rovnosti) v PHP je ==, jedno = je priradenie. Čiže zmeň podmienky:
if ($url == "blog1"){
                include 'includes/blog/article-1.php';
                } elseif ($url == "blog2") {
                include 'includes/blog/article-2.php';
                }

Odporúčam uzatvárať bloky kódu podmienky do zložených zátvoriek a to aj v prípade, že sú tvorené jediným príkazom, uľahčuje to prehľadnosť a rozšíriteľnosť kódu.
Tomáš123
Profil
lionel messi:
Prvá a základná do očí bijúca chyba
To som čítal aj na péhapku... Vraj aj profesionáli s tým majú problém. Znamená to že som profík? :-) (nie je nutné písať odpoveď...Ja ju dobre poznám).

S úpravou už zobrazuje iba požadovanú stránku, avšak pri indexe, kde nie je žiadny prídavok k URL, resp. pridá sa iba kľúč page, bez kľúču article, vyhadzuje poznámku o nedefinovanej premennej $url.
Kód:
<?php
    if ($url == "blog1")
        include 'includes/blog/article-1.php';
    elseif ($url == "blog2")
        include 'includes/blog/article-2.php';
    elseif ($url == "blog") 
        include 'includes/blog/index.php';            
?>

Odporúčam uzatvárať bloky kódu podmienky do zložených zátvoriek a to aj v prípade, že sú tvorené jediným príkazom
Mne stačí tabulátorom posunutý riadok :-) V prípade dlhšieho kódu sa určite budem tejto rady držať.
juriad
Profil
Tomáš123:
OK, chápu, třeba se k tomu za pár dnů vrátíš.

Počkej, asi nechceš na 6. řádku provádět include, ne? Chceš přece jen nastavit proměnnou $url na něco, co není blog1 a není blog2.
Tedy 6. řádek změň na: $url = "home";

A do toho velkého ifu uprostřed stránky přidáš:
else {
include "includes/index.php";
}

„Odporúčam uzatvárať bloky kódu podmienky do zložených zátvoriek a to aj v prípade, že sú tvorené jediným príkazom“
Mne stačí tabulátorom posunutý riadok :-) V prípade dlhšieho kódu sa určite budem tejto rady držať.
PHP jakékoli bílé znaky ignoruje, proto je jedno jak co odsadíš a nebude trvat dlouho a budeš se divit, proč to sakra dělá něco jiného??
Tomáš123
Profil
juriad:
OK, chápu, třeba se k tomu za pár dnů vrátíš.
Samozrejme :-)

Počkej, asi nechceš na 6. řádku provádět include, ne?
Chcem... Chcem aby sa v prípade že nie je špecifikovaný kľúč article načítala stránka index.php?page=blog, kde bude výber článkov. Môj plán rozpoloženia si môžeš pozrieť v #29 príspevku. Stále je tam záloha, v prípade, že nie je špecifikovaný druhý alebo žiadny kľúč. Cesta includu "includes/index.php" je záloha v prípade neuvedenia ani jedného kľúča.

*hore je to popísané trochu inde, preto hovoríme o iných cestách...Aj ja som sa pomýlil pri plnení štruktúry môjho plánu :-). Avšak v #29 príspevku by to malo byť správne.

Po pridaní "=" do podmienky sa zobrazí obsah includovanej časti súčasne s iným obsahom a podmienky nemiznú. (Veď prečo by aj mali? Stále je nedefinovaná premenná o 2 a o 4 riadky vyššie.) Ako prepísať podmienky? Alebo mám radšej použiť switch?
Micruss
Profil
Jsem si teda nikdy nevšimnul :D ani nezkoušel u isset, tak aspoň jsem zase o něco chytřejší dík :D
Kubo2
Profil
lionel messi:
Prvá a základná do očí bijúca chyba

Máš pravdu, mal ju zanesenú aj v kóde [#24] na predošlej strane. Je to len moja nevšímavosť, alebo to bolo to neskorou nočnou hodinou?


Tomáš123:
Chcem aby sa v prípade že nie je špecifikovaný kľúč article načítala stránka index.php?page=blog

Povedzme:

<?php

if(empty($_GET['article'])) {
    $url = 'blog';
} else if(!empty($_GET['page'])) {
    $url = $_GET['page'] . $_GET['article'];
}
Tomáš123
Profil
Kubo2:
Nakoniec som to vyriešil okopíroval takýmto spôsobom:
<?php
    if (isset($_GET['page'], $_GET['article'])) {
        $url = $_GET['page'].$_GET['article'];
    }
    elseif (isset($_GET['page'])) {
        $url = $_GET['page'];
    }
    else {
        include 'includes/index.php';
    }
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="css/default.css">
        <title>
            <?php echo $title;?>
        </title>
    </head>
    <body>
        <?php
            if (($url == "blog")) {
                include 'includes/blog/index.php';
            }
            elseif ($url == "blog1") {
                include 'includes/blog/article-1.php';
            }
            elseif ($url == "blog2") {
                include 'includes/blog/article-2.php';
            }
        ?>
    </body>
</html>

Ak budem mať ešte nejaký problém, určite sa ozvem, zatiaľ mám pocit, že som pochopil problematiku. V najbližšom čase (stále sa vyskytnú problémy, takže to nemusí byť v najbližšom čase...Ale budem sa snažiť) sa pokúsim prispieť do kategórie "Názor na stránku" kde nie len ty uvidíš, čo mám v pláne vyrobiť. :-)
Kubo2
Profil
Tomáš123:
To máš jedno, v podstate si znegoval moje predchádzajúce riešenie.
Tomáš123
Profil
Ahoj,
Znovu som sa vrátil ku tomuto problému. Predchádzajúce riešenie má veľa múch, tak som skúsil vytvoriť niečo podľa juriadovej ukážky. Kód som si párkrát prečítal a skúsil z toho, čo som si zapamätal vytvoriť niečo svoje:
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>PHP</title>
    </head>
    <body>
<?php
    if (!isset($_GET['cat'], $_GET['page'])) {
        include ('includes/index.php');
    }
    elseif (isset($_GET['cat']) && empty($_GET['page'])) {
        $path = "includes/".$_GET['cat']."/index.php";
        if (file_exists($path)) {
            include $path;
        }
        else {
        include ('includes/default.php');
        }
    }
    elseif (isset($_GET['cat'], $_GET['page'])) {
        $path = "includes/".$_GET['cat']."/".$_GET['page']."/index.php";
        if (file_exists($path)) {
            include $path;
        }
        else {
            include ('includes/default.php');
        }
    }
?>
    </body>
</html>
Objavilo sa však niekoľko problémov:
• Aj keď sú všetky podmienky splnené a súbor existuje, prehliadač ma poctí iba základnou stránkou, bez ohľadu na to, čo je za adresou;
• Žiadna chyba upozornenie či poznámka sa neobjavuje;

Prosím, pozrite sa mi ešte raz na ten kód. Možno je tam nejaká banálna chyba ako minule, možno je celý skript zle navrhnutý, sám to však posúdiť neviem.

Ďakujem
juriad
Profil
Přidej si před každý include echo s poznámkou. Tak snadno zjistíš, která varianta nastala.

Mimochodem, ta první podmínka dělá něco jiného než chceš - alespoň jeden neexistuje. A obecně je lepší psát podmínky v opačném pořadí - napřed nejkonkrétnější.

Obecně máš 9 variant, které musíš rozlišit (neplatnou a neexistující hodnotu rozeznáš až při testu file_exists):
1 cat existuje a je platná, page existuje a je platná
2 cat existuje a je platná, page existuje a je neplatná
3 cat existuje a je platná, page neexistuje
4 cat existuje a je neplatná, page existuje a je platná
5 cat existuje a je neplatná, page existuje a je neplatná
6 cat existuje a je neplatná, page neexistuje
7 cat neexistuje, page existuje a je platná
8 cat neexistuje, page existuje a je neplatná
9 cat neexistuje, page neexistuje

Schématicky, bez použítí else nebo else-if (to by kód jen zamotalo, protože jednotlivé části nejsou disjunktní):
$included = false
if(cat && page) {  1 2 4 5
  if(exists(cat/page/index)) { 1
    include cat/page/index
    included = true
  }
}

if(cat && ! included) { 2 3 4 5 6
  if(exists(cat/index)) { 2 3
    include cat/index
    included = true
  }
}

if(! included) { 4 5 6 7 8 9
  include index
}
Tomáš123
Profil
juriad:
Na základe pokusov s echom a vďaka vete „A obecně je lepší psát podmínky v opačném pořadí - napřed nejkonkrétnější.“ som vymenil poradie podmienok. Aktuálny kód vyzerá takto:
<?php
    if (isset($_GET['cat'], $_GET['page'])) {
        $path = "includes/".$_GET['cat']."/".$_GET['page']."/index.php";
        if (file_exists($path)) {
            echo "a";
            include $path;
        }
        else {
            echo "b";
            include ('includes/default.php');
        }
    }
    elseif (isset($_GET['cat']) && empty($_GET['page'])) {
        $path = "includes/".$_GET['cat']."/index.php";
        if (file_exists($path)) {
            echo "c";
            include $path;
        }
        else {
            echo "b";
            include ('includes/default.php');
        }
    }
    
    elseif (!isset($_GET['cat'], $_GET['page'])) {
        echo "d";
        include ('includes/index.php');
    }
?>

Teraz všetky kombinácie platnosti, neplatnosti a existencie vracajú očakávané písmená.

Až teraz som pochopil tvoj schematický príklad. Pôvodne som si myslel, že musím prerobiť celý skript, tak som skúsil radšej to s echom. Posledná otázka teda nie je aktuálna. Vyriešené, ďakujem juriad.
Tomáš123
Profil
Zdravím, napadlo mi, že systém adries pomocou $_GET je veľmi prospešný a potrebný aj pri menšom počte podstránok. Uvedomil som si však, že môj najlepšie funkčný výtvor, určite nesiaha ani po členky skutočnej metóde a overovaniu adries iných stránok.

Juriadova ukážka je na tom už o niečo lepšie, ale počíta s tým, že každý súbor v požadovanom adresári sa volá index.php a nikde nie je cesta ku 404 (namiesto úpravy som sa rozhodol porozmýšľať nad vlastným riešením).

Hotové riešenie, by som si predstavoval nejako takto (heslovite samozrejme):
<?php
  $dir = ".";
  $directories = readdir($dir); // Návratovou hodnotou funkcie nie je pole. Šlo by to pomocou glob()?
  //ideálne by bolo viac-rozmerné pole v tvare 1 => dir = array('clanok1', 'clanok2', 'clanok3')
  if(isset($_GET['section'] and is_string($_GET['section']) and in_array($_GET['section'], $directories)) {
    $path = $_GET['section']."/";
     if(isset($_GET['page'] and is_string($_GET['section']) and in_array($_GET['page'], $directories)) {
       $path .= $_GET['page'].".php";
     }
     else {
       $path .= $_GET['section'].".php";
     }
  }
  elseif(empty($_GET['section']) {
    $path = "default.php";
  }
  else {
    $path = "error.php";
  }
?> 
Mohli by ste mi prosím zhodnotiť zraniteľnosť (čo môže užívateľ zadať, aby mu vyšiel nečakaný výsledok)?

Taktiež mi nenapadá, ako vytvoriť to vysnívané viac-rozmerné pole. Ak nahliadneme do manuálu funkcie readdir(), vidíme príklad so správnym a nesprávnym vyťahovaním údajov. Prečo to musíme robiť tak, ako je to uvedené v správnej ceste (while (false !== ($entry = readdir($handle))) {)? Absolútne nerozumiem prečo to musí byť tak. Bol by niekto taký dobrý a vysvetlil mi, prečo sa to musí takto?
pcmanik
Profil
Tomáš123:
Nejak som sa v tom zamotal a rozhodne sa mi nechce čítať 2 stránky príspevkov.

Aký máš formát URL?
A o čo sa vlastne snažíš?

Namiesto neustáleho vyťahovania starého vlákna (ktoré nikdo znovu čítať nebude) by bolo možno lepšie založiť nové s aktuálnym problémom.
Tomáš123
Profil
pcmanik:
Aký máš formát URL?
index.php?section=nieco&page=nieco
Ide o to, aby sa cesta poskladala z parametrov:
Ak nie je uvedený žiadny parameter a súbor existuje: $path = "default.php";
Ak sú uvedené obidva parametre a súbor existuje: $path = $_GET['section']."/".$_GET['page'].".php";
Ak je uvedený iba prvý parameter a súbor existuje: $path = $_GET['section']."/".$_GET['section'].".php";
V akomkoľvek inom prípade (súbor musí existovať): $path = "error.php"; //404

V každej zložke mám vytvorený okrem iných súborov aj súbor, ktorého názov je rovnaký ako názov adresára, v ktorom sa nachádza. V prípade, že v URL nebude druhý parameter, zobrazím iba výpis článkov. Napríklad URL: www.nieco.sk/index.php?section=css zobrazí výpis článkov kategórie CSS a cesta ku súboru bude vyzerať /css/css.php.

A o čo sa vlastne snažíš?
Vytvoriť prepracovaný systém tvorenia adries, ktorý vie, aké adresáre existujú a podľa toho vie usúdiť, akú stránku zobraziť (vrátane 404). Systém by mal byť natoľko zabezpečený, aby som ho mohol použiť na verejne dostupných stránkach, teda by nemal nikdy zobraziť neočakávanú informáciu, či zlyhať (vinou programátora).

by bolo možno lepšie založiť nové s aktuálnym problémom
Už to tu raz bolo a duplicity sú nevítané. Celé je to stále o tom istom. Od mojej prvotnej otázky ako na parametre za adresou, cez prvé funkčné kódy až po snahu vyšperkovať a použiť riešenie.
pcmanik
Profil
Tomáš123:
Niečo ako toto?
if (isset($_GET['section']) && isset($_GET['page']) && file_exist($_GET['section'] .'/'. $_GET['page'] . '.php')) include $_GET['section'] .'/'. $_GET['page'] . '.php';
elseif (isset($_GET['section']) && !isset($_GET['page']) && file_exist($_GET['section'] .'/'. $_GET['section'] . '.php')) include $_GET['section'] .'/'. $_GET['section'] . '.php';
elseif (!isset($_GET['section']) && !isset($_GET['page']) && file_exist('default.php')) include 'default.php';
else include 'error.php';

Lepšie riešenie je ale použiť databázu.
Tomáš123
Profil
pcmanik:
Niečo ako toto?
Áno, ale skoro presne to, čo si uviedol som mal pred pár mesiacmi ([#12]). Problém bol ale v tom, že skript neošetroval neexistenciu adresáru (ktorá by sa ale dal relatívne ľahko implementovať). Skôr mi išlo o niečo, čoho nefunkčný príklad som napísal vyššie [#13]. Skúsil som si vytvoriť vlastnú funkciu, ktorá vyberie obsah aktuálneho adresára a vypíše ho v poli (teoreticky ani nebola potrebná funkcia (definoval som ju preto, aby prechádzala adresáre rekurzívne)). Nanešťastie, potom, čo nefungovala som ju musel rapídne zjednodušiť. A stále nefunguje:
function dir_get_contents($dir) {
  if(is_dir($dir)) {
    $dir = scandir($dir);
    return $dir;
  }
  else {
    return false;
  }
}
Jej volanie v podobe:
if ($success = dir_get_contents("./")) {
  echo 'true';
  foreach($dir as $directory) {
    echo $directory;
  }
}
else {
  echo 'false';
}
vygeneruje chybu: Warning: Invalid argument supplied for foreach() in /cesta on line 34

Asi bude lepšie, upraviť to do podoby kódu, ktorý si pridal a vložiť tam ošetrenie prípadu neexistencie adresára. Aj tak by ma ale zaujímala odpoveď na otázku nachádzajúcu sa pod kódom v [#13]
pcmanik
Profil
Tomáš123:
Keď nebude existovať adresár funkcia file_exist vrati false, takže skončíš na error.php

A v tvojom kóde sa snažíš prejsť neexistujúcou premennou $dir.
Tomáš123
Profil
pcmanik:
sa snažíš prejsť neexistujúcou premennou $dir
$dir je inicializovaný o niečo vyššie a má hodnotu "./".
pcmanik
Profil
Tomáš123:
$dir je inicializovaný o niečo vyššie a má hodnotu "./".
Dir je incializovaný vo vnútri funkcie teda spadá do iného oboru platnosti a v globálnom obore nemáš prístup k premenným ktoré su vo vnútri funkcie - v tomto prípade dir_get_contents.
Myslím že skorej chceš prechádzať premennou $success...
Tomáš123
Profil
pcmanik:
Myslím že skorej chceš prechádzať premennou $success...
Aha, jasné, ďakujem.
Kubo2
Profil
Tomáš123:
definoval som ju preto, aby prechádzala adresáre rekurzívne
A čo takto použiť DirectoryIterator?

/**
 * @param string
 * @return array
 * @throws \InvalidArgumentException
 */
function dir_get_contents($dir) {
    $error = false;
    if(!is_string($dir)) {
        $error = sprintf('Invalid argument 1 supplied for %s; expected string but %s given.', __FUNCTION__, gettype($dir));
    } else if(!is_dir($dir)) {
        $error = "Argument 1 must be a valid directory path.";
    }
    if($error) throw new \InvalidArgumentException($error);

    $contents = [];
    foreach(new \DirectoryIterator($dir) as $entry) {
        if($entry->isFile()) {
            $contents[] = $entry->getPathName();
        } else if($entry->isDir() && !$entry->isDot()) {
            $contents = array_merge($contents, dir_get_contents($entry->getPathName()));
        }
    }

    return $contents;
}

(netestované, za príp. chyby neručím) Po menšom teste zväčša prepísané.
« 1 2

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: