Sind diese PHP Methoden nützlich?

3 Antworten

Bei den Funktionen, die direkt Werte verarbeiten, die von außen kommen, wäre ich restriktiver. Für getContentSite sollte z.B. sichergestellt sein, dass wirklich nur die beabsichtigten PHP-Seiten aufgerufen werden können. Sammel die am besten in einem speziellen Ordner, in dem niemals andere PHP-Dateien abgelegt werden.

Da die Funktion versucht, die Datei direkt einzubinden, würde ich sie etwas anders benennen.

function includeContentSite($defaultSite) {
  if (!isset($_GET['site'])) {
    require_once($defaultSite . ".php");
    return;
  }

  $site = basename($_GET['site']);
  include_once('path/to/content/sites/folder' . $site . '.php');
}

Noch viel besser wäre allerdings ein Routingsystem, welches den Seitenname nicht an eine Datei, sondern eine Funktion knüpft. Zunächst werden alle Anfragen auf einen Dispatcher (index.php o.ä.) umgeleitet. Dort werden alle erwarteten URLs mit ihren zugehörigen Handlern verknüpft und gespeichert. Wenn die Request-URL auf einen bestimmten registrierten Eintrag passt, wird der dazugehörige Handler ausgeführt. Eine einfache Umsetzung wird in diesem Artikel gezeigt, andernfalls gibt es fertige (und ausgereiftere) Implementationen in diversen PHP-Frameworks (Laravel, Symfony, Yii, etc.).

Genauso solltest du restriktiver in getFormAction handeln. Schau erst, ob site einen validen, beabsichtigten Wert beinhaltet, bevor du ihn an eine Adresse hängst. Insofern könnte man sich da auch gleich eine Hilfsfunktion schreiben:

function getContentSiteName($defaultSite) {
  if (!isset($_GET['site'])) {
    return $defaultSite;
  }

  $site = basename($_GET['site']);
  $sitePath = 'path/to/content/sites/folder' . $site . '.php';

  if (file_exists($sitePath)) {
    return $site;
  }

  return $defaultSite;
}

function getFormAction() {
  $siteName = getContentSiteName('');

  if (!$siteName) {
    return $_SERVER['PHP_SELF'];
  }

  return '?site=' . $siteName;
}

Wenn es einen Querystring gibt, genügt diese relative Adresse. Andernfalls wird der aktuelle Dateiname ausgegeben, damit das action-Attribut, in welches der Wert später hineingeschrieben wird, nicht leer ist.

Hinsichtlich der Funktionen isFormValueChecked und isFormValueSelected kann ich nicht so viel sagen, da sich mir der Kontext nicht erschließt, in dem sie später eingesetzt werden.

Bei der Angabe des Connectionstrings würde sich, aufgrund der vielen Stringkonkatenationen eine Interpolation mal mehr lohnen:

$con = new PDO("mysql:host={$server};dbname={$schema};charset=utf8", $user, $password);

Und insgesamt könnte man alle Datenbankoperationen gut in einer Klasse kapseln:

class DatabaseHandler {
  public function __construct() {
    /* create PDO connection here ... */
    $this->connection = $connection;
  }

  public function makeStatement($query, $params = null) {
    try {
      $stmt = $this->connection->prepare($query);
      $stmt->execute($params);
      return $stmt;
    }
    catch(Exception $ex) {
      $this->printException($ex);
      return null;
    }
  }

  /* etc. */
}

// usage example:
$dbHandler = new DatabaseHandler();
$result = $dbHandler->makeStatement('select something from somewhere');
$otherResult = $dbHandler->makeStatement('select somethingElse from somewhereElse');

Auf eine globale Variable $con kann man somit verzichten. Die Rolle übernimmt das connection-Feld, welches nur in dem Kontext bekannt ist, in welchem es auch benötigt wird. Wenn du eine der Funktionen aufrufen möchtest, legst du dir eine Instanz der Klasse an und rufst über diese die jeweilige Funktion auf.

Achte im Übrigen darauf, konsistent bei der Werterückgabe zu sein. Wenn eine Funktion in einem ihrer Programmzweige einen Wert zurückgibt, dann sollte sie das letztendlich auch in allen anderen möglichen Programmzweigen tun.

Im obigen Fall (makeStatement) gibt es dahingehend zwei Möglichkeiten. Entweder du gibst bei Misserfolg null (oder zumindest einen anderen falsy Wert) zurück oder du verzichtest auf das try-catch und lässt eine Exception stattdessen nach oben eskalieren, um sie dann dort entsprechend zu behandeln.

Wenn du die erste Option wählst, könnte ein Aufrufer wie makeTable demzufolge so vorgehen:

public function makeTable($query, $arrV = null) {
  $stmt = $this->makeStatement($query, $arrV);

  if ($stmt) {
    /* print table ... */
  }
  else {
    /* fallback? */
}

Andernfalls bleibt es bei einem try-catch-Konstrukt.

Zu guter Letzt wäre es noch gut, die Namen einiger Bezeichner nochmals zu überdenken. Beispielsweise sollte $r doch eine Spalte repräsentieren und daher besser $column heißen. Bei $arrV oder $array wiederum ist von außen unklar, wozu sie dienen sollen. Ihr Zweck wird erst ersichtlich, wenn man sich den konkreten Code der jeweiligen Funktionen anschaut.

Moin,

also ich finde die Funktionen super. Sie sind schön kurz gehalten und man weiß genau was die einzelnen Funktionen machen.

PS. Schön das sich Neulinge an PHP trauen, da es online meist eher schlecht dargestellt wird. Aber mit den neusten Updates ist es echt super.

Viel Erfolg beim weiteren lernen.

LG.

Woher ich das weiß:Studium / Ausbildung – Bin Softwareentwickler

guteantwort626  29.05.2024, 00:24
also ich finde die Funktionen super

Als Informatiker sollte dir aber aufgefallen sein, dass man so etwas

include_once($_GET['site'] . ".php");

NIE machen darf. Damit hat man sich direkt eine tolle Hintertür eingebaut, mit der jede mögliche PHP Datei ausgeführt werden kann. Wenn es dann noch einen Dateiupload gibt, der die Dateiformate nicht überprüft, hat man eine RCE.

0

So könntest du beispielsweise deine PHP Funktionen mit HTML verknüpfen und dir deine Einträge in Tabellen anzeigen

index.php

<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css">
    <title>Document</title>
</head>


<body>
    <h1>CusSysMgmt</h1>


    <div class="contain-to-grid">
        <nav class="top-bar" data-topbar>


            <section class="top-bar-section">
                <ul class="left">
                    <li class="active"><a href="index.php?site=firstPage">Main</a></li>
                    <li class=""><a href="index.php?site=secondPage">Second</a></li>
                </ul>
            </section>
        </nav>
    </div>
    <?php
    include_once ("helper.php");
    getContentSite("index");
    ?>


</body>


</html>

firstPage.php

<?php
$servername = "localhost";
$username = "root";


try {
    $conn = new PDO("mysql:host=$servername;dbname=bs", $username);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


    $sth = $conn->prepare("SELECT cus_vorname, cus_nachname FROM Customer;");
    $sth->execute();
} catch (PDOException $e) {
    echo "Connection failed: " . $e->getMessage();
}


?>


<!-- Filter -->
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Filter by Nachname">
<script>
    function myFunction() {
        var input, filter, table, tr, td, i, txtValue;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();
        table = document.getElementById("myTable");
        tr = table.getElementsByTagName("tr");


        for (i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[1];
            if (td) {
                txtValue = td.textContent || td.innerText;
                if (txtValue.toUpperCase().indexOf(filter) > -1) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    }
</script>



<!-- Table generation -->
<table class="table" id="myTable">
    <th>Vorname</th>
    <th>Nachname</th>
    <?php
    while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
        ?>
        <tr>
            <td><?php echo $row['cus_vorname']; ?></td>
            <td><?php echo $row['cus_nachname']; ?></td>
        </tr>
        <br>
    <?php } ?>
</table>


<!-- Add New Customer To Table -->
<label> Add New Customer to Database</label><br>
<form action="index.php" method="POST">
    <label>Vorname: </label><input type="text" name="vorname"><br>
    <Label>Nachname:</Label><input type="text" name="nachname"><br>
    <input type="submit">
</form>
<?php
if (isset($_POST['vorname']) && isset($_POST['nachname'])) {
    $vorname = $_POST['vorname'];
    $nachname = $_POST['nachname'];
    $stmt = $conn->prepare('INSERT INTO Customer (cus_vorname, cus_nachname)
        VALUES (?, ?)');
    $stmt->execute([$vorname, $nachname]);
}
?>



<!-- Delete from Table -->
<label> Delete from Database via Nachname</label><br>
<form action="index.php" method="POST">
    <Label>Nachname:</Label><input type="text" name="nachnameDelete"><br>
    <input type="submit">
</form>
<?php
if (isset($_POST['nachnameDelete'])) {
    $nachname = $_POST['nachnameDelete'];
    $stmt = $conn->prepare('DELETE FROM Customer WHERE cus_nachname=?');
    $stmt->execute([$nachname]);
}
?>

secondPage.php

<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>


<body>
    <h1>Second Page</h1>
</body>


</html>
Woher ich das weiß:Berufserfahrung