« 1 2
Autor Zpráva
Fisir
Profil
Reaguji na Tomáše123:
Jestli ty složky pojmenováváš sám, opravdu to není nutné. Píšu to ze zvyku automaticky, urlencode() zajistí, že s URL nebude mít nikdo potíže v případě, že bude obsahovat nějaké nestandardní znaky, htmlspecialchars() zajistí to samé v textu odkazu. I když je pravda, že složky by se měly pojmenovávat tak, aby se tam žádná sekvence vyžadující escapování nevyskytla.
Tomáš123
Profil
Zdravím, mám malú otázočku... Dá sa nejako zistiť aktuálny stav parametrov za adresou (v horšom prípade i celú adresu)?
Potreboval by som to do podmienky, ale moja jednoduchá predstava nefunguje: if ($_GET == $path) ... Ako dostanem podobnú hodnotu?
lionel messi
Profil
Tomáš123:
Dá sa nejako zistiť aktuálny stav parametrov za adresou?
Napríklad http://jecas.cz/server#query-string a s týmto už dokážeš pracovať lepšie ($_SERVER["QUERY_STRING"]).
Tomáš123
Profil
lionel messi:
Vedel by si mi pomôcť ešte s jednou vecou? Súbor s informáciami o článku vyzerá približne takto:
home|Domov|./
about|O webe|index.php?section=about
css|CSS|index.php?section=css
html|HTML|index.php?section=html

Parametre sú od seba oddelené zvislicou. Skriptom sa snažím získať pole, ktoré bude pozostávať z prvého prvku riadka (výstupom by teda malo byť home about css html):
<?php
    $file = 'informations.txt';
    if ($read = fopen($file, 'r')) {
        while (!feof($read)) {
            $line = fgets($read);
            list($english, $slovak, $path) = explode('|', $line);
            $categories[] = $english;
            foreach ($categories as $category) {
                echo $category." za ".$category." ";
            }
        }
    }
    else {
        echo "<p>Súbor sa nepodarilo otvoriť.</p>";
    }
?>

Vo výstupe sa prvky usporiadajú 1 1 2 1 2 3 1 2 3 4... Stále to začína odznova. Ako upraviť skript, aby som dostal iba 1 2 3 4?
Tomáš123
Profil
Možnou príčinou faktu, že sem nikto nepíše môže byť tušenie, že pre odpoveď musíte prečítať všetky príspevky, čo sa nikomu nechce. Všetko pred touto čiarou, už nikto čítať nemusí.


Podarilo sa mi vypísať zo súboru všetky záznamy, ktoré majú niečo spoločné s kategóriou. Skript vyzerá takto:
<?php
    if (isset($_GET['section'])) {
        $file = 'information.txt';
        if ($read = @fopen($file, 'r')) {
            while (!feof($read)) {
                $line = fgets($read);
                list($section, $slovak, $path) = explode('|', $line);
                if ($_GET['section'] == $section) {
                    $aside_content = "<li><a href=\"".$path."\">".$slovak."</a></li>\n";
                }
            }
        }
    }
?>

Problémom však je, že neviem ako premennú vypísať na určené miesto po procese includu celej stránky (pred includom je to dosť zložité, keďže musím porovnávať cesty a každý súbor manuálne inicializovať). Na výstup sa vtedy dostane iba jedna premenná, ktorej obsah neviem upraviť. Je aj iná možnosť, ako dosadiť potrebný reťazec tam, kam patrí ako vypisovať obsah, ktorý by sa za normálnych okolností načítal naraz manuálne? Ak niekomu nie je na otázke niečo jasné, prosím, pýtajte sa, rád to objasním. Vopred ďakujem.

Aby bolo jasné, o čo sa snažím, ide mi o vlastnú administráciu s pridávaním a upravovaním článkov, pričom všetky budú uložené v jednom súbore. Vyššie uvedený skript porovnáva zhodu a mal by vypísať odkazy na články vrámci tej istej kategórie.
Tomáš123
Profil
[#5]: Uvedomil som si, že jediné, čo musí byť menené je iba konkrétny obsah. Čiže vyššie uvedený problém už nie je aktuálny, ale objavil sa nový. Myslím, že budem potrebovať pracovať s regulárnymi výrazmi. Podstatou je, že na výstup sa môže dostať iba ten obsah, ktorého adresa vyzerá následovne: index.php?section=xxxx. Podmienkou je, aby obsahovala iba prvý parameter. Ak sa odkazujem na článok, parametre sú dva. Neviem si predstaviť niečo, čo dokáže porovnať adresu takýmto spôsobom. Viete mi pomôcť? Ak sem napíšete konkrétny regulárny výraz,
mohli by ste pripojiť krátke vysvetlenie, ktorá časť, na čo slúži? Ďakujem pekne.
Kubo2
Profil
Tomáš123:
Neviem si predstaviť niečo, čo dokáže porovnať adresu takýmto spôsobom. Viete mi pomôcť?

Ako to, že nie? Ak som správne pochopil, vcelku použiteľné je k tomu superglobálne pole $_GET. Čo ďalej chceš na tom porovnávať, tobôž ešte preháňať regulárnymi výrazmi?

// index.php?section=xxx&article=yyy
$sectionId  = $_GET[ 'section' ];
$articleId  = $_GET[ 'article' ];
Tomáš123
Profil
Kubo2:
Iste, takto by sa to dalo, ale ja potrebujem vybrať zo súboru, takže suberglobálne pole mi veľmi nepomôže. Potrebujem získať tie riadky, v ktorých sa nenachádza druhý parameter, teda z riadkov:
css|CSS|index.php?section=css
css|Názov článku v kategórii CSS|index.php?section=css&page=nazov-clanku

sa na výstup musí dostať iba ten prvý.

Alternatívnym riešením je pridať riadku ďalšie parametre (niečo ako hlavná kategória alebo článok) a porovnávať tieto hodnoty. Ozvem sa, keď sa mi podarí toto riešenie spracovať...
Fisir
Profil
Reaguji na Tomáše123:
Asi by ti s tím mohl pomoci můj návod, s využitím funkcí parse_url() a parse_str().
Tomáš123
Profil
Ahojte, podarilo sa mi ako tak sprevádzkovať administráciu (ak to tak môžem nazvať). V ukážke si môžte skúsiť pridať články.

Mám však niekoľko problémov:
1. Skript, ktorý pridáva články povolí nevyplniť polia. Neviem čo robím zle... Riadok, ktorý by tomu mal zamedziť vyzerá takto:
if (isset ($_POST['section'], $_POST['access'], $_POST['title'], $_POST['content'])) {
Žiadne chybové hlásenie sa nevypíše. Iba sa jednoducho pridajú do súboru neúplné informácie, čo spôsobí, že sa článok nezobrazí tam, kde má.

2. Chcel by som, aby mala domovská stránka základnú adresu. Zatiaľ to tak je, ale články pridané do kategórie „domov“ sa nezobrazia v bočnom paneli. Pravdepodobne to bude štruktúrou skriptu, ktorý ich ťahá:
if (isset($_GET['section'])) {
        $file = 'informations.txt';
        if ($read = @fopen($file, 'r')) {
            while (!feof($read)) {
                $line = fgets($read);
                list($section, $title, $path, $cat, $access) = explode('|', $line);
                if ($_GET['section'] == $section && $cat == 'sec' && $access == 'public') { /*Skúšal som aj niečo v zmysle: if ($_GET['section'] == $section or $section == 'home') {, ale vypisovalo mi to iba chybu o nedefinovanej premennej $section*/
                    echo "<li><a href=\"".$path."\">".$title."</a></li>\n";
                }
            }
            fclose ($read);
        }
    }
Riadok, ktorý by sa mal načítať vyzerá asi takto:
home|home|index.php?section=home&page=home|sec|public|
Teda v postrannom paneli kategórie „Domov“ by sa malo zobraziť slovo 'home'.
Obsah by sa zobrazil, ale iba na podstránke index.php?section=home (pokojne si to vyskúšajte, článok tam je)... Nechcem mať toto ako základnú stránku. Rozumiete o čo mi ide?

Vedeli by ste mi poradiť, ako prerobiť podmienky?

Fisir:
V dobe, keď si mi poslal odkaz sa mi celkom darilo, tak som to dokončil. Aj tak som tvojmu návodu veľmi nerozumel (nie tvojou vinou).

EDIT: Ako pravdepodobne Marschmallow ukázal, stránka sa dá hacknúť. Prosím nekazte mi to, ide o názornú ukážku pridávania článkov, nie zabezpečenia administrácie!
Marschmallow
Profil
Tomáš123:
Ako pravdepodobne Marschmallow ukázal, stránka sa dá hacknúť.
Ano, byl jsem to já. Pakliže to bude administrace a bude zaheslovaná, nemá skoro cenu nějakou ochranu dělat. Vytvořil jsem si externí HTML soubor, do kterého jsem dal formulář s action="index.php?section=administration&page=adding". Tím jsem vlastně nasměroval cizí požadavek na Tvůj skript a ten ho zpracoval.
Tomáš123
Profil
Ešte by som sa rád vrátil k tomuto problému. Nevidím absolútne žiadnu chybu, všetko by malo byť tak, ako má. Prezrite si prosím skript:
<?php
    $title = 'Pridávanie článkov';
    if (isset ($_POST['section'], $_POST['access'], $_POST['title'], $_POST['content'])) {
        $file = 'informations.txt';
        $written = false;
        $dir_exists = false;
        if ($write = @fopen($file, 'a+')) {
            while (!feof($write)) {
                $line = fgets($write);
                list($section, $title, $path, $cat, $access) = explode('|', $line);
                $path = $_POST['section']."/".$_POST['title'].".php";
                if (is_dir($_POST['section']) && $_POST['title'] !== $title && !file_exists($path)) {
                    $newtitle = $_POST['title'];
                    $data = "\n".$_POST['section']."|".$_POST['title']."|index.php?section=".$_POST['section']."&page=".$newtitle."|sec|".$_POST['access']."|";
                    fwrite ($write, $data);
                    fclose ($write);
                    $written = true;
                    $dir_exists = true;
                    break;
                }
            }
            if ($dir_exists !== false) {
                echo "<p>Adresár, do ktorého chcete pridávať obsah neexistuje.</p>";
            }
            if ($written !== false) {
                if ($open = @fopen($path, 'w')) {
                    if ($write = fwrite($open, $_POST['content'])) {
                        echo "<p>Do súboru sa podarilo úspešne zapísať obsah.</p>";
                    }
                    else {
                        echo "<p>Obsah súboru sa nepodarilo zapísať.</p>";
                    }
                }
                else {
                    echo "<p>Súbor sa nepodarilo vytvoriť.</p>";
                }
            }
        }
        else {
            echo "<p>Nastala chyba! Nepodarilo sa otvoriť súbor.</p>";
        }
    }
    else {
        echo "<p>Vyplňte prosím všetky formulárové polia!</p>";
    }
?>

EDIT: Podmienka vlastne nefunguje ani pri najjednoduchšej možnej verzii:

<?php 
  if (isset ($_POST['section'], $_POST['access'], $_POST['title'], $_POST['content'])) {
    echo "1";
  else {
    echo "0";
  }
?>


Myslel som, že zlú spoluprácu podmienok by mohlo spôsobiť, že sa vo formulári odkazujem na spracúvajúci skript prostredníctvom iného skriptu:
<form method="post" action="index.php?section=administration&page=adding">
Bohužiaľ aj potom, čo som adresu zmenil situácia pretrváva. Po pridaní súboru, sa normálne vypíše text "<p>Do súboru sa podarilo úspešne zapísať obsah.</p>", ale ak napríklad neexistuje adresár, alebo nevyplním všetky polia, nedostane sa mi žiadna odpoveď...

Je pravda, že už viackrát som mal v pláne prestať otravovať, ale naozaj neviem, čo s tým.

Budem vďačný ak mi to pomôžete vyriešiť.
Kubo2
Profil
Tomáš123, skús použiť empty(). isset() ti dáva istotu, že premenné z formulára boli odoslané, nie však, či boli pôvodné políčka vyplnené.
lionel messi
Profil
Kubo2:
skús použiť empty()
Nevýhoda empty spočíva vo vrátení FALSE v prípade 0.
Tomáš123
Profil
Kubo2, lionel messi:
Skúsil som to s empty() a funguje to! Nerozumiem ale, prečo takáto úprava robí divy (myslím ako div sveta, nie html div)...

isset() ti dáva istotu, že premenné z formulára boli odoslané, nie však, či boli pôvodné políčka vyplnené.
Ale veď aj v preklade to znamená, či je nastavená (hodnota). Ako to, že pri použití v inom prípade to fungovalo bezproblémovo?

Nerozumiem rozdielu medzi správnym a nesprávnym použitím... Čo je podmienkou správneho výsledku? Nesmiem porovnávať <select>-y? Môžte mi to prosím vysvetliť?
Kubo2
Profil
Ale veď aj v preklade to znamená, či je nastavená (hodnota).
Ale význam je mierne odlišný. isset() kontroluje, či je nastavená premenná, a ak je, tak či jej hodnota !== null. Všimni si však, že vráti true aj v prípade, že jej predáš prázdny reťazec (pretože premenná doslova existuje).

empty() v takom prípade vráti true, pretože premenná obsahuje jednu z hodnôt, ktorá sa pri pretypovaní na boolean vyhodnotí ako false, čiže ide doslova o hodnotu, ktorá sa pokladá za prázdnu.
Tomáš123
Profil
Kubo2:
Rozumiem, je teda o niečo rozsiahlejšie riešenie kontroly vyplnenia polí (každé pomocou !empty(), keďže táto funkcia nepreberá viac parametrov) bežné, alebo sa to bežne rieši iným spôsobom?

V mojom prípade by ten riadok musel vyzerať takto:
if (!empty ($_POST['section']) && !empty($_POST['access']) && !empty($_POST['title']) && !empty($_POST['content'])) {
Kubo2
Profil
Tomáš123:
Áno, žiaľ, je to dosť nešťastné, ale takto sa to bežne rieši. Aj keď skôr by som si už napísal nejaký automatický OOP násttroj na generovanie formulárov, ako to takto bežne riešiť.
Kcko
Profil
Tomáš123:
Ne můžeš to řešit i jinak.

$mandatoryFields = ["section", "access", "title", "content"];

$error = FALSE;
foreach ($mandatoryFields as $field)
{
    if (empty($_POST[$field])
    {
        $error = TRUE;
        break;
    }

}


if ($error) {}
else {}

Samozřejmě by se to mělo řešit nějakou OOP obálkou, doporučil bych Ti NETTE, ale k tomu máš hodně daleko ... tak snad takhle aspoň
Kubo2
Profil
Niečo ako:

 <?php

interface IRenderable {
    public function render();
    public function __toString();
}

interface IForm extends IRenderable, Iterator, ArrayAccess {
    const METHOD_GET = 'GET';
    const METHOD_POST = 'POST';

    public function isSent();
    public function isValid();
    public function addElement(IFormElement $elem);
    public function __construct(/* string */ $action, /* string */ $method = IForm::METHOD_GET);
}

interface IFormElement extends IRenderable, ArrayAccess {
     public function __construct( $name, $value = NULL ); // druh elementu je určený typom konkrétnej triedy 
} 

interface IFormInput extends IFormElement {
    const CONSTRAINT_DISABLED = 0x10; // dec 16
    const CONSTRAINT_REQUIRED = 0x20; // dec 32
    // ... another constraints

    public function setConstraint( $constraint );
} 

phpDoc k tomu písať nebudem, lebo jednak myslím, že kontrakty jednotlivých metód sú priam intuitívne, a jednak je už aj tak dosť neskoro.

Jednu vec ti poradím: naštuduj si to, naštuduj si OOP, skús tomu porozumieť a testuj to, skúšaj, vytvor si triedy s definovanými rozhraniami, len tak sa niečo naučíš.
Tomáš123
Profil
Kubo2, Kcko:
Hou, hou, hou, pomaly chlapci. :-)

Ak toho bude viac, použijem Kckove riešenie, zatiaľ to ponechám tak. Ďakujem

Vedeli by ste mi pomôcť aj s druhým problémom?

Kubo2:
naštuduj si OOP
Aj na to príde čas...
« 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:

0