Extragere informatii din baza de date si afisare in page.php

Lucrez la un mic site in php si vreau sa extrag informatiile din baza de date in fisierul page.php. De exemplu pagina despre-noi sa se afiseze informatiile titlu si continu dar as dori sa aive si un permalink curat gen http://demosite.ro/despre-noi. Cineva care ma poate ajuta as fi recunoscator.
Momentan apare asa: http://demo.dev-zb.ro/page.php?page=despre
In fisierul page.php

<?php

error_reporting(E_ALL);

require_once 'dbconnect.php';

if(isset($_GET['page']) && $_GET['page'] != '')
{
    $page = mysqli_query($con, "SELECT * FROM pages WHERE slug = '{$_GET['page']}'") or die(mysqli_error($con));

    if(mysqli_num_rows($page) > 0)
    {
        $page = mysqli_fetch_assoc($page);

        include_once('views/view.php');

    }
    else die('Page doesn\'t exists!');
}
else die('Page doesn\'t exists!');

In view.php am codurile

<div class="container">
  <div class="row">
    <div class="col-md-12 content">

    <h1><?php echo $page['title']; ?></h1>

    <?php echo $page['pagetext']; ?>

   </div><!-- end .col-md-12 -->
 </div><!-- end .row -->
</div><!-- end .container -->

Uite, poate te ajuta :wink:

Using htaccess Files for Pretty URLS

2 Likes

RewriteRule ^(.*)/?$ page.php?&page=$1 [QSA]

adresa va fi de forma : http://demo.dev-zb.ro/servicii/ cu acel / la sfarsit !
Adauga asta in htacces !

1 Like

Așa cum e acum, codul tău e vulnerabil la MySQL injection.
Folosește cu încredere mysqli_real_escape_string() sau prepared statements.

Altă problemă o am cu acel or die(). Pe Google vei găsi o grămadă de explicații detaliate de ce nu-i o idee bună. Dacă chiar ții să scrii cod puțin, mai degrabă pui ceva de genul:

function showErrorPage() {
    include_once('views/error.php');
    die();
}

mysqli_query('...') or showErrorPage();

1 Like

In admin la adaugare pagina am asta:
http://pastebin.com/8FheFCqt
E ok asa?

Este ok faptul că folosești $mysqli->real_escape_string().

Sugestii:

  • În loc de !empty($_POST) îți sugerez $_SERVER['REQUEST_METHOD'] === 'POST'. E mai lung, dar, teoretic, te interesează să continui procesarea doar dacă datele au fost trimise prin POST. S-ar putea ca formularul să fi fost trimis prin POST, dar fără a completa nici un câmp, caz în care $_POST este empty(). Ceea ce mă duce la punctul următor…
  • Nu faci nicăieri validarea datelor! $_POST s-ar putea să nu fie gol, dar s-ar putea să-ți lipsească o parte din câmpuri (poate ai apăsat <Enter> din greșeală înainte să completezi câmpul slug). Întotdeauna verifică existența și validitatea datelor (de exemplu, un câmp de email să nu fie doar prezent, ci să aibă și un format valid). După care…
  • Generează mesaje de eroare corespunzătoare! Dacă verifici câmpul slug, în cazul că e gol, eroarea să specifice că acel câmp este obligatoriu. Dacă nu este gol, verifică dacă nu există deja o altă pagină în baza de date cu acel slug iar, în caz contrar, generează un mesaj de eroare care să informeze utilizatorul cu privire la asta, să înțeleagă ce se întâmplă.
  • Din nou, abuzezi de die(). Generează mesaje de eroare informative, afișate corespunzător în pagină.
  • Separă HTML-ul de PHP. Câmpul $message putea foarte bine să conțină doar textul, fără tag-ul <h3> iar în HTML, unde afișezi mesajul, să ai ceva de genul
<?php if (!empty($message)) : ?>
  <h3><?php echo htmlentities($message, ENT_QUOTES, 'UTF-8'); ?></h3>
<?php endif; ?>
  1. Encoding-ul este deja default UTF-8 din PHP 5.4, deci poate fi ignorat dacă folosești ceva echivalent sau mai nou
  2. Recomand folosire formelor “lungi” ale structurilor de control (if: endif; for: endfor; while: endwhile;, etc) doar atunci când sunt folosite pentru generarea de cod HTML, pentru îmbunătățirea lizibilității
  3. Pentru a simplifica lucrurile poți folosi o funcție ajutătoare în secțiunile de afișare
<?php
function html($str, $output = TRUE) {
  $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
  if ($output) {
    echo $str;
  }

  return $str;
}
?>

// ...și codul devine:
<?php if (!empty($message)) : ?>
  <h3><?php html($message); ?></h3>
<?php endif; ?>

Ah, și recomandarea mea (dar asta nu-i standard și e subiect de dezbatere) este să nu folosești string interpolation, mai ales atunci când nu este vorba despre o simplă variabilă ci de o expresie, cum este în cazul tău

"VALUES ( '{$mysqli->real_escape_string($_POST['title'])}', ..."

# mai degrabă 
$title = $mysqli->real_escape_string($_POST['title']);
"VALUES ( '{$title}', ..."
# ...sau chiar (preferata mea)
"VALUES ( '" . $title . "', ..."

5 Likes

Multumesc mult de raspuns. Unul destul de bun de altfel.

Daca e sa fiu carcotas, nici real_escape_string nu e sigur, fiindca poti face smecherii cu encoding-ul, rezultand intr-un SQL injection. Doar preparem statements e mai sigur, fiindca se comunica in 2 stagii, mai intai interogarea, apoi valorile, si asta face o injectare mai dificil de creat.

Deci ce-ar fi sa incepi de pe-acuma OOP @bucur si sa faci new PDO() etc.?

1 Like

Sunt la inceput in php si na am ezitari si greseli de incepator :))
Sunt constient ca trebuie sa fac si asta OOP.

1 Like

No, că mă plictiseam și m-am jucat puțin… Cam așa ar fi structura pe care ți-aș sugera-o, ca începător:

(Aici ai tot codul funcțional: http://1drv.ms/1QQoVBu )

index.php :

<?php

require_once 'bootstrap/_init.php';

$errors = array();
$data   = array(
    'title'   => NULL,
    'content' => NULL,
    'slug'    => NULL,
);

// dacă request-ul este de tip POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // sunt eliminate spațiile de la începutul și sfârșitul string-urilor
    foreach ($_POST as $key => $value) {
        $data[$key] = trim($value);
    }

    // validare titlu (5 caractere sunt doar un exemplu arbitrar)
    if (strlen($data['title']) < 5) {
        $errors['title'] = 'Titlul trebuie să aibă o lungime de minim 5 caractere';
    }

    // validare conținut
    if (empty($data['content'])) {
        $errors['content'] = 'Conținutul paginii nu poate fi gol';
    }

    // validare existență `slug`
    if (empty($data['slug'])) {
        $errors['slug'] = 'Câmpul "slug" este obligatoriu';
    } else {
        // validare unicitate slug
        $result = $DB->query('SELECT `slug` FROM `pages` WHERE `slug` = "' . $DB->escape_string($data['slug']) . '" LIMIT 1');
        $result or render('db-error') and exit();

        if ($result->num_rows) {
            $errors['slug'] = 'Există deja o pagină cu URL-ul "' . $data['slug'] . '"';
        }

        $result->close();
    }

    if (empty($errors)) {
        $data = array_map($DB->escape_string, $data);

        $DB->query('INSERT INTO `pages` SET
            `title`   = "' . $data['title'] . '",
            `content` = "' . $data['content'] . '",
            `slug`    = "' . $data['slug'] . '"
        ') or render('db-error') and exit();

        redirect('?success');
    }

}

// toate cheile celui de-al doilea parametru vor fi disponibile ca variabile în template: $errors, $success, $data
render('add-form', array(
    'errors'  => $errors,
    'success' => isset($_GET['success']),
    'data'    => $data
));

?>

bootstrap/functions.php:

<?php

function redirect($url) {
    header('Location: ' . $url);
    exit();
}

function render($page, $data = NULL) {
    $view = 'views/' . $page . '.php';
    $data = (array) $data;

    extract($data);
    include($view);

    return TRUE;
}

function html($str, $output = TRUE) {
    $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
    $output and print($str);

    return $str;
}

?>

wiews/add-form.php:

<style type="text/css">
input.error,
textarea.error {
    border: 1px solid #c00;
}

.errors {
    margin: 20px 0;
    padding: 10px;
    background: #900;
    color: #fff;
}

.success {
    margin: 20px 0;
    padding: 10px;
    background: #090;
    color: #fff;
}
</style>

<h1>Adăugare pagină</h1>


<?php if($errors): ?>
<ul class="errors">
    <?php foreach($errors as $error): ?>
    <li><?php html($error)?></li>
    <?php endforeach;?>
</ul>
<?php endif; ?>


<?php if($success): ?>
    <div class="success">Pagina a fost salvată!</div>
<?php endif; ?>


<form action="?" method="POST">
    Titlu:
    <br />
    <input type="text" name="title" class="<?php echo isset($errors['title']) ? 'error' : ''; ?>" value="<?php html($data['title']); ?>" />
    <br /><br />

    Conținut:
    <br />
    <textarea name="content" class="<?php echo isset($errors['content']) ? 'error' : ''; ?>"><?php html($data['content']); ?></textarea>
    <br /><br />

    Slug:
    <br />
    <input type="text" name="slug" class="<?php echo isset($errors['slug']) ? 'error' : ''; ?>" value="<?php html($data['slug']); ?>" />
    <br /><br />

    <input type="submit" value="Salvează pagina" />
</form>
4 Likes

Cum as putea sa iti multumesc incat sa intelegi ce mult apreciez ce ai facut. Multumesc mult.

Cred că cea mai bună apreciere ar fi să întrebi ce nu ai înțeles din codul de mai sus, astfel încât să și înveți ceva :wink:

2 Likes

Ce sa mai un forum grozav. :grinning:

1 Like

(postări retrase de autor, vor fi şterse automat în 24 ore, cu excepţia cazului în care mesajele sunt marcate)

Poti sa repostezi fisierul de download te rog !

Nu inteleg ce fisier vrei?

Nu știu de ce nu mai merge link-ul vechi, că n-am șters fișierul. https://1drv.ms/u/s!An_PqVEtNQkik9RXRBvoPzbwFmidbA

1 Like

Multumesc mult de tot !