Dynamisches Erstellen von Webseiten mit PHP

MusicJunkie666

Commander
Registriert
März 2013
Beiträge
2.757
Servus,
da ich a) kein passendes CMS für meine private Webseite gefunden habe und b) den Umgang mit PHP und MySQL üben will, habe ich vor, mir mein eigenes CMS zu basteln. Als "Vorlage" habe ich mir "simpleCMS" von css-tricks.com hergenommen.
Das klappt auch bisher ganz gut, Posts erstellen, in die DB schreiben und Anzeigen funktioniert.
Aber: Ich möchte für jeden Post ein Unterverzeichnis mit index.php, die den Post aus der DB auslesen und anzeigen soll.
So dass Besucher als URL nur domain.tld/blog/lorem-ipsum/ statt domain.tld/blog/index.php&id=1234 sehen.

Mir ist aber nicht klar, wie ich das machen kann. Ich habe es auf folgende Weise probiert:
Beim Erstellen eines Posts werden aus dem Titel alle Leer- und Sonderzeichen entfernt. Dann wird mit diesem String ein Verzeichnis erstellt, darin wird per fopen eine index.php erstellt. Soweit so gut.
Nun war meine Idee, den Inhalt für diese index.php aus einem von mir erstellten Template auszulesen und mit den spezifischen Daten zum Post (Titel und ID) zu ergänzen.
Das funktioniert aber nicht, weil ich dazu PHP-Code in eine Variable laden und in das neue File schreiben muss. Suboptimal.

Wie könnte ich das noch lösen? Könnt ihr mir da mit einem Lösungsansatz entgegen kommen?

Die "Haupt"-PHP Datei, in der der Code steht:
PHP:
<?php

class simpleCMS {

  var $host;
  var $username;
  var $password;
  var $table;

public function display_post_full($id){

        $sql_conn = new mysqli($this->host,$this->username,$this->password,'CMSDB');
        if ($conn->connect_error) {
                die("Connection failed: " . $conn->connect_error);
        }

        $sql_qery = "select * FROM CMSDB WHERE created = $id";
        $sql_conn->query($sql_query);
        while($row = $result->fetch_assoc()){
                echo $row['title'] . '<br />';
                echo $row['bodytext'] . '<br />';
        }
        }


  public function display_public() {
    $q = "SELECT * FROM CMSDB ORDER BY created DESC LIMIT 3";
    $r = mysql_query($q);

    if ( $r !== false && mysql_num_rows($r) > 0 ) {
      while ( $a = mysql_fetch_assoc($r) ) {
        $title = stripslashes($a['title']);
        $bodytext = stripslashes($a['bodytext']);
         $bodytext_short = substr ( $bodytext, 0, 50) . '...';
        $created = intval(stripslashes($a['created']));
        $postdate = date('D' , $created) . ', ' . date('d' , $created) . '. ' . date('m' , $created) . '. ' . date('o' , $created);



 $entry_display .= <<<ENTRY_DISPLAY

    <div class="post">
        <h2>
                $title
        </h2>
        <h6>
                $postdate
        </h6>
            <p>
              $bodytext_short
            </p>
        </div>

ENTRY_DISPLAY;

      }
    } else {
      $entry_display = <<<ENTRY_DISPLAY

    <h2> This Page Is Under Construction </h2>
    <p>
      No entries have been made on this page.
      Please check back soon, or click the
      link below to add an entry!
    </p>

ENTRY_DISPLAY;
    }
    $entry_display .= <<<ADMIN_OPTION

    <p class="admin_link">
      <a href="{$_SERVER['PHP_SELF']}?admin=1">Add a New Entry</a>
    </p>

ADMIN_OPTION;

    return $entry_display;
  }

  public function display_admin() {
    return <<<ADMIN_FORM

    <form action="{$_SERVER['PHP_SELF']}" method="post">

      <label for="title">Title:</label><br />
      <input name="title" id="title" type="text" maxlength="150" />
      <div class="clear"></div>

      <label for="bodytext">Body Text:</label><br />
      <textarea name="bodytext" id="bodytext"></textarea>
      <div class="clear"></div>

      <input type="submit" value="Create This Entry!" />
    </form>

    <br />

    <a href="index.php">Back to Home</a>

ADMIN_FORM;
  }

  public function write($p) {
    if ( $_POST['title'] )
      $title = mysql_real_escape_string($_POST['title']);
    if ( $_POST['bodytext'])
      $bodytext = mysql_real_escape_string($_POST['bodytext']);
    if ( $title && $bodytext ) {
      $created = time();
      $this->createpage($title, $created);
      $sql = "INSERT INTO CMSDB VALUES('$title','$bodytext','$created')";
      return mysql_query($sql);
    } else {
      return false;
    }
  }

  public function connect() {
    mysql_connect($this->host,$this->username,$this->password) or die("Could not connect. " . mysql_error());
    mysql_select_db($this->table) or die("Could not select database. " . mysql_error());

    $sql_conn = new mysqli($this->host,$this->username,$this->password,'CMSDB');
    if ($sql_conn->connect_error) {
        die("Connection failed: " . $sql_conn->connect_error);
    }

    return $this->buildDB();
  }


  private function createpage($title, $created) {
        $link = $title;
        function clean($link) {
                $link= str_replace(' ', '-', $link);
                return preg_replace('/[^A-Za-z0-9\-]/', '', $link);
        }
        mkdir("../$link");
        $newfile = fopen("../$link/index.php", "w+");

        $templfh = fopen ("template.php", "r");
        $template = fread ($templfh, filesize("template.php"));

        $output_array = explode("~", $template);
        if ($created) {
        $output = $output_array[0] . $title;
        $output .= "$output_array[1]" . "$created" .  "$output_array[2]";
        }

        fwrite($newfile, $output);
        fclose ($templfh);
        fclose($newfile);
  }

  private function buildDB() {
    $sql = <<<MySQL_QUERY
CREATE TABLE IF NOT EXISTS CMSDB (
title           VARCHAR(150),
bodytext        TEXT,
created         VARCHAR(100)
)
MySQL_QUERY;

    return mysql_query($sql);
  }

}

?>

Die template.php
PHP:
<!DOCTYPE HTML>
<!--
        Striped by HTML5 UP
        html5up.net | @n33co
        Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
        <head>
                <title>~ domain.tld</title>
                <meta http-equiv="content-type" content="text/html; charset=utf-8" />
                <meta name="description" content="" />
                <meta name="keywords" content="" />
                <!--[if lte IE 8]><script src="css/ie/html5shiv.js"></script><![endif]-->
                <script src="../../js/jquery.min.js"></script>
                <script src="../../js/skel.min.js"></script>
                <script src="../../js/skel-layers.min.js"></script>
                <script src="../../js/init.js"></script>
                        <link rel="stylesheet" href="../../css/skel.css" />
                        <link rel="stylesheet" href="../../css/style.css" />
                        <link rel="stylesheet" href="../../css/style-desktop.css" />
                        <link rel="stylesheet" href="../../css/style-wide.css" />
                <!--[if lte IE 8]><link rel="stylesheet" href="css/ie/v8.css" /><![endif]-->
        </head>
        <body class="left-sidebar">

                        <div id="wrapper">

                                        <div id="content">
                                                <div class="inner">

                                                                <article class="box post post-excerpt">
                                                                        <p>
<?php

  include_once('simpleCMS.php');
  $obj = new simpleCMS();
  $obj->host = 'localhost';
  $obj->username = '*zensiert*';
  $obj->password = '*zensiert*';
  $obj->table = 'CMSDB';
  $obj->connect();

  if ( $_POST )
    $obj->write($_POST);

  echo ( $_GET['admin'] == 1 ) ? : $obj->display_public_short(~);

?>
                                                                        </p>
                                                                </article>
                                                </div>
                                        </div>

                                        <div id="sidebar">

                                                        <h1 id="logo"><a href="#">TAFART</a></h1>

                                                        <nav id="nav">
                                                                <ul>
                                                                        <li class="current"><a href="#">Start</a></li>
                                                                        <li><a href="/about">About Me</a></li>
                                                                        <li><a href="/contact">Contact Me</a></li>
                                                                        <li><a href="/impressum">Impressum</a></li>
                                                                        <li><a href="/blog">Blog</a></li>
                                                                </ul>
                                                        </nav>
                                                        <ul id="copyright">
                                                                <li>&copy; Untitled.</li><li>Design: <a href="http://html5up.net">HTML5 UP</a></li>
                                                        </ul>

                                        </div>

                        </div>

        </body>
</html>
 
Die übliche Lösung ist, den Webserver so zu konfigurieren (z. B. Apache mit mod_rewrite), dass er Requests der Form /blog/* intern umleitet auf (z. B.) /blog.php. In dem PHP-Programm wertet man dann den URL aus und entscheidet, welchen Post man anzeigen will. Dadurch spart man sich das ganze Gefummel mit dem Dateisystem.
 
Ja, daran habe ich noch gar nicht gedacht. Das klingt fast nach der optimalen Lösung.
Mal schauen, wie ich automatisiert Weiterleitungen erstellen kann...

Danke!
 
Die beste Art, Weiterleitungen zu definieren, ist übrigens NICHT, so etwas wie /blog/* auf blog.php?* zu leiten. Bei so einer statischen Lösung kriegst du ganz schnell Stresspusteln, weil du für jede Erweiterung der Seite dein Webserver-Konfiguration ändern muss. Totaler Mist.

Das Zauberwort heißt "Routing".
Schnapp dir ein anständiges Framework, die bringen alle auch eine Router-Funktion mit. Dabei werden alle Anfragen, die nicht auf explizite Dateien abzielen, stur auf die Index.php geleitet. Soll die doch den Ärger haben.

In der .htaccess sieht das dann auf immer und ewig so hier aus:
Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule .* index.php [L]
Wenn "Anfrage" weder existierende File (!-f), Directory (!-d) oder Symlink (!-l), dann schleif die Parameter an die index.php durch.
 
Zurück
Oben