– support stone thrones tickoon zoo ristoo fi,der otelo finder

Présentation

PHP: Hypertext Preprocessor est un langage libre de 1994. Exécuté coté serveur web, il peut générer du code HTML.

php 1

Avantages

  • populaire
  • interprété par le serveur, indépendant de l’OS
  • non verbeux
  • création de page web dynamiques
  • disponible sur tous les hébergements

Inconvenients

  • syntaxe fouillie, ajout de l’objet à posteriori
  • prise en charge des types incomplete
  • plus lent et moins  à la mode que NodeJS

Utilisation

Il peut être déployé sur différents serveurs web comme

  • Internet Information Services IIS, de Microsoft
  • Apache HTTP Server de la Apache Software Foundation
  • lighttpd de Jan Kneschke ;
  • nginx d’Igor Sysoev ;

Attention, les anciens accès aux bases MySQL sont dépréciés (mysql_query par exemple).

Les métiers

Premier code

On doit indiquer les balises HTML et insérer du code PHP.
Tout code PHP commence par une balise < ?php et termine par ?> sauf pour les fichiers 100% PHP.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>mon titre</title>
</head>

<body> 
<?php 
echo "Je suis un script PHP qui va être affiché en HTML » ; 
?> 
</body> 
</html>

Envoie du code HTML depuis le serveur PHP

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>mon titre</title>
</head>

<body> 
Je suis un script PHP qui va être affiché en HTML 
</body> 
</html>

Toutes les variables commencent par des $, on termine les lignes d’instructions par des ;
Par défaut il n’y a pas de type de variables.

<?php 
$a=5;
//commentaire
/*com-
mentaire */

Inclusion de code

On utilise include ou require pour importer du code. Il sera alors exécuté à l’endroit où il est inséré.
L’instruction require bloquera le script si une erreur survient, par exemple si le fichier n’est pas trouvé.
On peut utiliser require_once ou include_once pour n’inclure qu’une seule fois le script.

maPage.php

<?php  echo « meumeu » ;

secondePage.php

<?php require_once ‘maPage.php’;

Changement automatique de page

On souhaite aller sur le site de Google en appelant une page
Il est nécessaire de ne pas placer de sortie HTML avant le header. Une balise HTML provoquera une erreur de la fonction header (On lui demande de changer de page alors qu’on lui a passé un script qui génère une page, d’où le conflit)

<?php 
header("Location: http://www.google.com/");  
/* Pour être certain que le code se bloque à la redirection*/ 
exit; 

Le typage

Il est possible d’obliger les fonctions à prendre certains types pour leurs paramètres.  De grandes évolutions depuis la version 7.2

public function test(int $a) { 
        echo $a; 
    }

Variables prédéfinies

PHP possède plusieurs variables utiles accessibles sur vos pages.
http://www.php.net/manual/fr/reserved.variables.php

Les variables HTTP

Un tableau associatif des valeurs passées au script courant via le protocole HTTP et la méthode POST. Cf formulaire

session_start();
$_POST[‘monNameDeInput’] ;

Un tableau associatif des valeurs passées au script courant via le protocole HTTP et la méthode GET. Cf formulaire

session_start();
$_GET[‘monNameDeInput’] ;

Un tableau associatif des valeurs passées au script courant via le protocole http. Il contient les variables de $_GET, $__POST et $_COOKIE

session_start();
$_REQUEST[‘monNameDeInput’] ;

Les variables de sessions

Un tableau associatif des valeurs stockées dans les sessions, et accessible au script courant.
On pourra s’intéresser par la suite au tableau associatif cookie et files.

session_start();
$_SESSION[‘maVariable’] =28;

Les formulaires

form1

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>mon titre</title>
</head>
<body>

<form method="post" id="frmConnection" action="recuperation.php">
    <label for="email"> Votre email:</label>
    <input type="email" name="txtEmail" id="txtEmail" autofocus />
    </br>
    <label for=" txtPass "> Mot de passe :</label>
    <input type="password" name="txtPass" required />
    <input type="submit" name="cmd" id="cmd" value=" envoie " />
</form>

</body>
</html>

 

Fichier recuperation.php
On récupère les champs d’un formulaire grâce aux attributs name
La fonction isset() vérifie que le paramètre est renseigné. Si le champ n’est pas rempli dans le formulaire, la variable n’existera pas dans recuperation.php, ce qui génère une erreur si on y accède.

<?php session_start();

if (isset($_POST[‘txtEmail’])) {
    echo $_POST[‘txtEmail’];
}

Retour sur même page de formulaire

maPage.php
La page sera rechargée avec l’affichage des données entrées

<?php session_start()?>

<!DOCTYPE html>
<html>
<head>

    <meta charset="utf-8" />
    <title>mon titre</title>
</head>
<body>

<?php

if(isset($_POST["cache"])){
    echo "vos valeurs ".$_POST[txtEmail]." ".$_POST[txtPass];

}else{
    ?>
    <form method="post" id="frmConnection" action=" maPage.php">
        <label for="email"> Votre email:</label>
        <input type="email" name="txtEmail" id="txtEmail" autofocus />
        </br>
        <label for=" txtPass "> Mot de passe :</label>
        <input type="password" name="txtPass" required />
        <input type="hidden" name="cache" id=" cache " value="1" />
        <input type="submit" name="cmd" id="cmd" value=" envoie " />
    </form>
    <?php
}
?>
</body>
</html>

Tableau associatif

Création d’un tableau associatif  à deux dimensions et affichage

 $produits = [
    'bulbes' => ['poids' => 200, 'quantite' => 9, 'prix' => 15],
    'rosiers' => ['poids' => 10, 'quantite' => 20, 'prix' => 2],
    'massifs' => ['poids' => 10, 'quantite' => 30, 'prix' => 6]
 ];

echo $produits['bulbes']['quantite'];


echo '<br> <br>';

foreach ($produits as &$value) {
  //  echo $value['quantite'].' ';
    foreach ($value as &$ssvalue) {
        echo $ssvalue;echo '<br>';
    }
}

Liste déroulante dynamique

$mesCLients est un tableau d’objet Client contenant l’email et d’autres variables

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>mon titre</title>
</head>
<body>

<?php
$mesClients =["Lina","Winie","John","Harry"];
print("<select name=’maListe’ size=’1’>");

    foreach($mesClients as client){
    print("<option>".$client." </option>");

    }
    print("</select >");
?>
</body>
</html>

Lecture écriture de fichier

écriture

file_put_contents('exemple.json', json_encode($produits));

réécriture

file_put_contents('exemple.json', 'waza',FILE_APPEND);

lecture

$mesproduits = file_get_contents('exemple.json');

Exemple d’écriture d’un tableau en fichier json et récupération en php

<?php 


 $produits = [
    'bulbes' => ['poids' => 200, 'quantite' => 9, 'prix' => 15],
    'rosiers' => ['poids' => 10, 'quantite' => 20, 'prix' => 2],
    'massifs' => ['poids' => 10, 'quantite' => 30, 'prix' => 6]
 ];

echo $produits['bulbes']['quantite'];


foreach ($produits as &$value) {
  //  echo $value['quantite'].' ';
    foreach ($value as &$ssvalue) {
        echo $ssvalue;echo '<br>';
    }
}


file_put_contents('exemple.json', 'Ecriture dans un fichier');
file_put_contents('exemple.json', 'Ecriture dans un fichier2',FILE_APPEND);

var_dump(json_encode($produits));
var_dump($produits);
file_put_contents('exemple.json', json_encode($produits));
file_put_contents('exemple.json', 'waza',FILE_APPEND);
$mesproduits = file_get_contents('exemple.json');
var_dump($mesproduits);

$b=json_decode($mesproduits, true);
var_dump($b);

//file_put_contents('exemple.json',"\n waza",FILE_APPEND);
$json_errors = array(
    JSON_ERROR_NONE => 'No error has occurred',
    JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
    JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
    JSON_ERROR_SYNTAX => 'Syntax error',
);
 echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
 
?>

Connexion aux bases de données

L’API PDO

L’API PDO est une interface de programmation d’application (Application Programming Interface). Elle regroupe les classes qui vont permettre de réaliser des fonctions aux SGBDR via PHP.,L’API PDO requiert PHP 5.1 au minimum. Attention, les anciens accès aux bases MySQL sont dépréciés (mysql_query par exemple). On ne peut donc plus les utiliser. Ils sont considérés comme non sécurisés et génère une alerte.,Toutefois, il n’est pas obligatoire d’utiliser PDO. D’autres API existent.

Si vous ne souhaitez pas d’une application portable sur plusieurs SGBDR et profiter au maximum des fonctionnalités qu’offre par exemple MySQL dans ses dernières versions, il faut utiliser l’API Mysqli. MySQLi pour Mysql improved permet d’avoir plus de fonctionnalités que PDO pour MySQL. Par contre, une grande partie du code sera à modifier si vous changez de SGBDR. Cette extension n’est utile qu’à partie de la version 4.3.1 de MySQL.

Création d’une connexion MySQL

Les paramètres du constructeur sont des chaines de caractères. Seul le premier est obligatoire.
On instancie l’objet PDO avec au minimum le Data Source Name ou DSN. Le DSN contient les informations pour se connecter à la BD du SGBDR quel que soit l’utilisateur. Le login et le mot de passe sont des paramètres optionnels.

Attention la syntaxe du Data Source Name est dépendante de chaque base de données. D’après le site de php.net :
Le try{}catch{} permet de capturer les exceptions déclenchées par la création de l’objet en cas d’erreurs.

<?php
$dsn='mysql:dbname=testdb;host=127.0.0.1';
$user='dbuser';
$password='dbpass';

try{
    $dbh=new PDO($dsn,$user,$password,array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); 
}catch(PDOException $e){
    echo'Connexion échouée:'.$e->getMessage(); 
}

PostgreSQL et port

<?php
$dsn = "pgsql:host=192.168.1.14;port=5432;dbname=maBase"; 
try { 
    $dbh = new PDO($dsn, »root », » »); 
} catch (PDOException $e) { 
    echo 'Connexion échouée : ' . $e->getMessage(); 
}

Exécution de requêtes

Après avoir réalisée une connexion, il est possible d’effectuer des requêtes. Deux manières s’offre à nous.

Exec

<?php
$sql="DELETEFROMclientWHEREnom='Dupond'";
 $count=$dbh->exec($sql);
print("Effacementde$countlignes.\n");

La fonction d’instance exec renvoie le nombre de lignes affectées par la requête. Cette fonction peut aussi générer des erreurs (généralement une erreur dans la requête SQL). Il est possible de les afficher grâce à l’instruction « or die ». On réutilise l’objet PDO dbh créé précédemment.

Query

Le nom des colonnes sera exactement les mêmes que celles de la base de données. Il faut éviter les accents et les espaces qui sont sources d’erreur lors du passage des informations du SGBDR au serveur PHP.

<?php
$sql="SELECT nom, prenom FROM client";
$statement=$dbh->query($sql) ordie(print_r($dbh->errorInfo(),true)); 
foreach ($statement->fetchAll(PDO::FETCH_OBJ) as $ligne) {
    echo 'Utilisateur : '.$ligne->nom.'<br>';
}
$statement->closeCursor();

Query exécute une requête SQL, retourne un jeu de résultats en tant qu’objet PDOStatement. La fonction setFetchMode de l’objet PDOStatement va influer sur l’accès des données.
Il faut imaginer le résultat sous forme de tableau. Ce tableau se nomme un curseur. Quand on exécute la fonction fetch, on place l’accès au curseur à la première ligne.

Nom Prenom
Durand Dinan
Daria David
Lini Louis

Pour passer à la deuxième ligne on exécute une nouvelle fois la fonction fetch.

Nom Prenom
Durand Dinan
Daria David
Lini Louis

Pour libérer la connexion du serveur PHP au SGBDR, on ferme le curseur (closeCursor). On accède à une case du tableau en étant d’abord sur la bonne ligne puis en accédant à la colonne correspondante.

Les requêtes préparées

Les requêtes préparées permettent d’améliorer les performances et la sécurité. Le pilote sera autorisé à utiliser le cache coté client ou serveur. Ce type de requête protège des injections SQL. Il n’est plus nécessaire d’utiliser des fonctions spécifiques pour s’en prémunir. La requête est préparée avec des variables appelées marqueurs que l’on va insérer dans la requête SQL. On peut ré-exécuter la requête de cette manière profitant pleinement du cache. On préférera cette méthode aux méthodes précédentes surtout pour des variables récupérées par un client.

exec

<?php
$sql="DELETE FROM client WHERE nom=:nom";
$statement=$dbh->prepare($sql);
$nom ="harry";
$statement->bindParam(":nom", $nom);
$b=$statement->execute();

Cette méthode bien que sécurisée, ne renverra que true dans la variable b ou false si elle n’est pas exécutée.

query

<?php
$sql = "SELECT nom, prenom FROM client WHERE login=:login AND mdp=:mdp";
$resultats = $dbh->prepare($sql);

$login = "login";
$mdp = "mdp";

$resultats->bindParam(":login", $ login);
$resultats->bindParam(":mdp", $mdp);
$resultats->execute(); 
foreach ($resultats->fetchAll(PDO::FETCH_OBJ) as $ligne) {
    
    echo 'Utilisateur : ' . $ligne->nom . '<br>';
}

PHP Objet

Les objets en PHP fonctionnent par référence. Si on enregistre un objet dans une variable, ce sera une référence vers cet objet qui sera enregistré.

La classe

client

<?php

class Client
{
    private $nom;

    public function getNom()
    {
        return $this->nom;
    }
} 

Utilisation d’un objet

$monClient = new Client();

On accède à une variable d’un objet de la manière suivante

$monClient->nom ;

L’objet this fonctionne dans une méthode d’instance comme en Java

$this->nom ;

Les visibilités

Les visibilités s’appliquent sur les variables et les fonctions. Elles sont identiques à Java : public, protected, ou private. On respectera les principes de l’encapsulation.

Comparaison d’objets

On utilise deux manières pour comparer les objets.

Le == permet de comparer les valeurs de l’objet. Ils doivent être de la même classe et posséder les mêmes variables de valeurs identiques.
Le === vérifie la référence de l’objet. L’objet doit donc ici être le même alors qu’avec l’autre méthode, l’objet doit être égal.

Les constantes

Ceci est différent de Java, on n’utilise pas le mot clef final

class A {
    const ZOZO= 'valeur constante';
}
printA::ZOZO;

Par contre le mot clef final est utilisé de la même manière pour les classes et les méthodes. Une méthode final ne pourra être surchargée et une classe final ne pourra être héritée.

 final public function waza() { 
       echo "c'est la fin !"; 
   } 

Le mot clef static

<?php

class A
{
    public static $maVarStatic = ‘titi‘;   
    public static function maFonction()
    {
        echo "ma fonction";
    }
}

printA::$maVarStatic;
printA::maFonction();

Parcours de collection

<?php
foreach ($collection as $key => $value) {
    print $key => $value;
     }
foreach ($collection as $value) {
    print $value;
}

Le constructeur

<?php

class Client
{
    function __construct()
    {
        print"constructeur de la classe mere";
    }
}

On note _ _ avant construct pour réaliser un constructeur.
Les méthodes ayant le même nom que la classe dans laquelle elle se trouve ne sont plus traitées comme des constructeurs.
Client() sera considérée comme une fonction et non comme un constructeur.

    function Client() { 
        print "simple fonction"; 
    }

Constructeur avec paramètres

class Client{ 
    function __construct($param1, $param2) { 
        print "constructeur avec 2 paramètres"; 
    } 
}

L’héritage

Comme en Java, Il n’est pas possible d’hériter de plusieurs classes. La notation des variables et méthides static est soulignée.

class Fille extends Mere{ }

her 1

Le mot réservé self désigne la classe elle-même (this). Le mot parent désigne la classe mère (super).

<?php

class Mere
{
    public static $maVarStatic = "titi";
    public $var;

    const CONST_VALUE = "Unevaleurconstante";

    public static function Value(){
     return self::$maVarStatic;
}

public static function maFonction(){}
public function maDeuxiemeFonction(){}
}

/*****************************************/

class Fille extends Mere
{
    public function renvoieStatic()
    {
        parent::maFonction();
        parent::$maVarStatic;
    }

    public function maDeuxiemeFonction()
    {
        parent::maDeuxiemeFonction();
    }
}

/*******************************************/
printMaFille::$maVarStatic;b

//accès à la variable static

$mam= new Mere();
$mam->var;

$fille = new Fille();
print $fille->renvoieStatic();

Constructeur

Parent remplace ici super de Java.

class Mere { 
    function __construct() { 
        print "constructeur de la classe mere"; 
    } 
} 

class Fille extends Mere { 
    function __construct() { 
        parent::__construct(); 
        print "constructeur de la classe fille"; 
    } 
}

Les classes et méthodes abstraites

Même comportement qu’en Java. Il est nécessaire d’implémenter les méthodes abstraites. La notation des classes abstraite est en italique.

ab 2

abstract class Personne
{ 
    // Force les classes filles à définir cette méthode 
    abstract protected function getValue(); 
    abstract protected function setValue($a); 

} 

class Client extends Personne
{ 
     protected function getValue() { 
       return "ConcreteClass1"; 
     } 

     public function setValue($a) { 
       return  $a; 
    } 
}

Les interfaces

Toutes les méthodes des interfaces doivent être implémentées dans la classe.

int

interface iTemplate 
{ 
    public function setVariable($name, $var); 
    public function getHtml($template); 
} 

class Template implements iTemplate 
{ 
    private $vars = array(); 
    public function setVariable($name, $var) 
    { 
        $this->vars[$name] = $var; 
    } 

    public function getHtml($template) 
    { 
        foreach($this->vars as $name => $value) { 
            $template = str_replace('{' . $name . '}', $value, $template); 
        } 

        return $template; 
    } 
} 

// Ceci ne fonctionnera pas 
class BadTemplate implements iTemplate 
{ 
    private $vars = array(); 
    public function setVariable($name, $var) 
    { 
        $this->vars[$name] = $var; 
    } 
}

Data Access Object Pattern

Un mapping objet et base relationnel permet de créer l’illusion d’une correspondance entre la base de données et les objets du langage de programmation. On fait donc correspondre les attributs des objets avec les attributs de la base de données. On parle d’ORM (object-relational mapping).  L’exemple qui suit est un DAO réalisé soi-meme. Il existe des ORM à installer comme Doctrine ou Eloquent.

Le pattern DAO consiste à ajouter un ensemble d’objets dont le rôle sera d’aller lire, écrire, modifier, supprimer. Cet ensemble d’objet s’appelle la couche DAO. Ce pattern utilise des classes génériques. On part de nos classes et on réalise des classes qui vont faire la liaison avec la base de données. Ces classes vont porter le nom du pattern : XxxDAO. Ces classes héritent d’une classe DAO qui définit la généricité.

dao

En PHP 7.4, les classes génériques ne sont pas encore implémentées. On utilise une interface à la place.

L’interface qui oblige nos classes DAO à implémenter ces fonctions

interface ManagerInterface {
     function setConnection() ;
       function select(int $id);
      function insert( $obj): bool;
      function update( $obj): bool;
      function delete( $obj): bool;
      function findAll(): array;

}

La classe Personne

 class Personne {

    private int $id;
    private string $nom;
 

    public function getId():int {
        return $this->id;
    }
    public function setId(int $id) {
        $this->id = $id;
    }
    public function getNom():string {
        return $this->nom;
    }
    public function setNom(string $nom) {
        $this->nom = $nom;
    }
    public function __toString(){
    	return $this->id." ".$this->nom;
    }
}

La classe PersonneDAO

<?php





 class PersonneDao implements ManagerInterface {
    private PDO $connection;
    


    
    public function setConnection() {
        $dsn='mysql:dbname=testdb;host=127.0.0.1';
    $user='root';
    $password='';
    try{
        $dbh=new PDO($dsn,$user,$password); 
        $this->connection=$dbh;
    }catch(PDOException $e){
        echo'Connexion échouée:'.$e->getMessage(); 
    }
        
    }
  
    public function insert( $obj):bool {
        $result=false;
        try {

        	/*$sql="SELECT max(id)+1 as id FROM personne";
            $statement=$this->connection->query($sql,PDO::FETCH_ASSOC) ;
            $row  = $statement -> fetch();
            $id=$row['id'];*/
            $id=$obj->getId();
            $nom=$obj->getNom();

        	$sql="INSERT INTO personne (id, nom) VALUES ( '$id' , '$nom')";
            echo $sql;
            $nbLignes=$this->connection->exec($sql) ;
            if($nbLignes==1)
              $result=true;
            
        } catch (PDOException $e) {
            echo'insert échoué:'.$e->getMessage(); 
        }
        return $result;
    }


    public function select(int $id):Personne {
         $p = new Personne();
        try {
            $sql="SELECT * FROM personne where id = '$id'";
            $statement=$this->connection->query($sql,PDO::FETCH_ASSOC) ;
            $row  = $statement -> fetch();
            $p->setNom($row['nom']);
            $p->setId($row['id']);
        } catch (PDOException $e) {
            echo'select échoué:'.$e->getMessage(); 
        }
        return $p;
    }




public function update( $obj):bool {
        $result=false;
        try {
      $id=$obj->getId();
            $nom=$obj->getNom();
        	$sql="UPDATE personne SET nom = '$nom' WHERE id = '$id'";
            echo $sql;
            $nbLignes=$this->connection->exec($sql) ;
            if($nbLignes==1)
              $result=true;
            
        } catch (PDOException $e) {
            echo'update échoué:'.$e->getMessage(); 
        }
        return $result;
 }


public function delete( $obj):bool {
        $result=false;
        try {
            $id=$obj->getId();
        	$sql="DELETE FROM personne WHERE id = '$id'";
            echo $sql;
            $nbLignes=$this->connection->exec($sql) ;
            if($nbLignes==1)
              $result=true;
            
        } catch (PDOException $e) {
            echo'delete échoué:'.$e->getMessage(); 
        }
        return $result;
 }

//ici le tableau ne contient pas des objets de type Personne
   public function findAll():array {
        $personnes = null;
        try {
            $sql="SELECT * FROM personne";
            $statement=$this->connection->query($sql);
            $personnes = $statement->fetchAll(PDO::FETCH_OBJ);


        } catch (PDOException $e) {
            echo'select all échoué:'.$e->getMessage(); 
        }
        return $personnes;
    }



}

echo "debut du programme";

$a=new Personne();
$a->setNom("harry");
$a->setId(32);
var_dump($a);

$b=new Personne();
$b->setNom("harold");
$b->setId(31);

$persodao=new PersonneDao();
$persodao->setConnection();
$persodao->insert($a);
$persodao->insert($b);

$a->setNom("jo");
$persodao->update($a);
$unePersonne=$persodao->select(32);
echo "<br><br>".$unePersonne."<br><br>";

$tb=$persodao->findAll();
var_dump($tb);
foreach ($tb as $row ) {
  echo  $row->nom."<br><br>";
 }
 $tb[] = $b;
var_dump($tb);


$persodao->delete($a);


/*CREATE TABLE IF NOT EXISTS `personne` (
  `id` int(11) NOT NULL,
  `nom` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
)*/
?>