Retour au blog

BTS SIO : les langages de programmation à maîtriser (Java, PHP, Python)

Les mêmes briques en Java, PHP et Python, les règles qui changent de l'un à l'autre et les pièges qui coûtent des points, avec trois exercices corrigés.

Cet article a été rédigé à des fins pédagogiques. Les informations présentées peuvent évoluer. Nous t’invitons à vérifier auprès de sources officielles.

La fiche officielle du BTS SIO ne nomme aucun langage de programmation : elle décrit des compétences, comme développer une application, interroger une base de données ou corriger un dysfonctionnement (fiche RNCP 40792). Maîtriser Java, PHP et Python, c'est donc maîtriser les mêmes briques dans trois écritures. Exemple : parcourir les nombres de 1 à 3 s'écrit for i in range(1, 4): en Python, for ($i = 1; $i <= 3; $i++) en PHP et for (int i = 1; i <= 3; i++) en Java. Seules quelques règles changent, et ce sont elles qui coûtent des points.

Ce que chaque langage apporte

PHP tourne sur le serveur web : quand un navigateur demande une page PHP, le serveur exécute le script, qui lit souvent une base de données, puis renvoie du HTML.

Java est compilé : un programme, le compilateur, traduit ton code avant son exécution par la machine virtuelle Java (la JVM). Son typage est statique : chaque variable a un type déclaré, int pour un entier par exemple, et le compilateur refuse d'y ranger autre chose. Tout s'y écrit dans des classes.

Python est interprété : tu lances ton fichier directement, sans compiler toi-même. Comme PHP, il a un typage dynamique : c'est la valeur qui porte le type, pas la variable. Il sert souvent aux scripts, ces petits programmes qui automatisent une tâche.

Les mêmes briques, trois syntaxes

Voici les briques de tous tes programmes, côte à côte :

BriquePythonPHPJava
Variablenb = 3$nb = 3;int nb = 3;
Conditionif nb > 2:if ($nb > 2) { }if (nb > 2) { }
Bouclewhile nb > 0:while ($nb > 0) { }while (nb > 0) { }
Fonctiondef carre(x): return x * xfunction carre($x) { return $x * $x; }static int carre(int x) { return x * x; }
Affichageprint(nb)echo $nb;System.out.println(nb);

En PHP, une variable commence toujours par le signe dollar. En PHP et en Java, chaque instruction finit par un point-virgule et les accolades encadrent les blocs ; Java exige en plus le type de chaque variable, de chaque paramètre et du résultat. Python s'en passe : les deux-points ouvrent un bloc et l'indentation, le décalage en début de ligne, le délimite.

Piège classique : en Python, l'indentation fait partie du code. Une ligne décalée d'un cran de trop entre dans la boucle et se répète à chaque tour. En PHP et en Java, seules les accolades comptent, mais indente quand même : ton correcteur lit ton code.

Division et égalité : là où ils divergent

Écris 7 / 2 dans les trois langages. Python et PHP donnent 3.5. Java donne 3 : entre deux entiers, sa division est entière, la partie décimale est coupée. Pour obtenir 3,5 en Java, mets un nombre décimal dans le calcul : 7.0 / 2. Dans l'autre sens, la division entière s'écrit 7 // 2 en Python et intdiv(7, 2) en PHP.

Le double égal == change lui aussi de sens. En Python, il compare deux valeurs, textes compris. En PHP, il compare après conversion : deux textes qui ressemblent à des nombres sont comparés comme des nombres, si bien que "1" == "01" vaut true. Le triple égal === compare sans rien convertir, et "1" === "01" vaut false (manuel PHP).

Piège classique : en Java, == entre deux objets vérifie qu'il s'agit du même objet en mémoire, pas qu'ils ont le même contenu. Ainsi saisie == "admin" peut valoir false alors que l'utilisateur a bien tapé admin. Pour comparer deux textes, écris saisie.equals("admin"). En PHP, préfère ===, qui ne convertit rien.

La programmation objet

Définition : une classe est un modèle qui décrit les données d'une famille d'objets (leurs attributs) et ce qu'ils savent faire (leurs méthodes). Un objet est un exemplaire créé à partir de ce modèle, avec ses propres valeurs. Le constructeur est la méthode appelée à sa création.

Voici un compte bancaire écrit en Java :

public class Compte {
    private double solde;

    public Compte(double depart) {
        solde = depart;
    }

    public void crediter(double montant) {
        if (montant > 0) {
            solde = solde + montant;
        }
    }
}

Le mot private interdit de toucher à solde depuis l'extérieur de la classe. Pour le modifier, il faut passer par crediter, qui ignore un montant négatif ou nul : c'est l'encapsulation, la classe protège la cohérence de ses données. On s'en sert ainsi : Compte c = new Compte(0); puis c.crediter(50);.

En PHP, le constructeur s'appelle __construct, un attribut se note $this->solde et l'objet se crée aussi avec new. En Python, le constructeur s'appelle __init__ et reçoit l'objet en premier paramètre, nommé self par convention ; on crée l'objet sans new : Compte(0). Python n'a pas de mot private : un tiret bas en tête de nom, comme _solde, signale seulement qu'on ne doit pas y toucher du dehors.

Des requêtes SQL sans injection

Une application de gestion interroge sa base de données en SQL, le langage de requêtes. Le danger vient de ce que tape l'utilisateur. Cette ligne PHP colle la saisie dans la requête :

$sql = "SELECT * FROM client WHERE nom = '" . $_GET['nom'] . "'";

Si quelqu'un tape ' OR '1'='1, la requête devient SELECT * FROM client WHERE nom = '' OR '1'='1'. La condition est toujours vraie et la base renvoie tous les clients : c'est une injection SQL, la saisie a été lue comme du code.

La parade est la requête préparée : un marqueur ? à la place de la valeur, et la valeur fournie à part ($pdo est la connexion à la base) :

$req = $pdo->prepare("SELECT * FROM client WHERE nom = ?");
$req->execute([$_GET['nom']]);

La saisie est alors traitée comme une valeur, jamais comme du SQL. Selon le manuel PHP, une application qui n'utilise que des requêtes préparées est à l'abri des injections, tant qu'aucune autre partie de la requête n'est construite avec une saisie. Java fait de même avec PreparedStatement, et le module sqlite3 de Python avec le même marqueur ?.

Piège classique : un marqueur remplace une valeur, jamais un nom de colonne, même derrière ORDER BY. Si ce nom vient de l'utilisateur, compare-le d'abord à une liste de valeurs permises.

Exercices corrigés

Du plus direct au niveau d'un contrôle. Cherche sur ta feuille avant d'ouvrir la correction.

Exercice 1 : Ce script Python doit afficher une seule fois le total d'un panier, en euros. Qu'affiche-t-il ? Corrige-le.

total = 0
for prix in [12, 8, 5]:
    total = total + prix
    print(total)

Correction :

La ligne print(total) est indentée comme celle du dessus : elle fait partie de la boucle et s'exécute à chaque tour. Le script affiche 12, puis 20, puis 25, sur trois lignes.

Ramène-la au niveau du for : elle s'exécute alors une seule fois, après la boucle, et affiche 25, soit 25 €.

Exercice 2 : Une boutique en ligne (données fictives) accorde 10 % de remise dès 100 € d'achat. Réécris cette fonction Python en Java, puis calcule ce qu'elle renvoie pour 4 articles à 25 €.

def total(prix, quantite):
    montant = prix * quantite
    if montant >= 100:
        montant = montant * 0.9
    return montant

Correction :

Java exige un type partout : double pour les sommes en euros, qui peuvent avoir des centimes, int pour la quantité.

static double total(double prix, int quantite) {
    double montant = prix * quantite;
    if (montant >= 100) {
        montant = montant * 0.9;
    }
    return montant;
}

Pour 4 articles à 25 € : $4 \times 25 = 100$. La remise s'applique dès 100 €, d'où le test >= et non > : $100 \times 0{,}9 = 90$. La fonction renvoie 90.0, soit 90 €.

Exercice 3 : Une page PHP liste les produits d'une catégorie, triés selon le choix du visiteur. Son auteur se croit protégé par sa requête préparée. A-t-il raison ? Corrige le code pour n'accepter qu'un tri par nom ou par prix.

$tri = $_GET['tri'];
$req = $pdo->prepare("SELECT nom, prix FROM produit WHERE categorie = ? ORDER BY " . $tri);
$req->execute([$_GET['cat']]);

Correction :

Non. La catégorie passe par le marqueur : elle est protégée. Mais $tri est collé tel quel dans la requête, et aucun marqueur ne peut le remplacer puisque c'est un nom de colonne. Un visiteur peut donc y glisser du SQL.

On compare le choix à une liste de valeurs permises, avec nom par défaut, en remplaçant la première ligne par :

$tri = $_GET['tri'] ?? 'nom';
if (!in_array($tri, ['nom', 'prix'], true)) {
    $tri = 'nom';
}

Le troisième argument, true, rend la comparaison stricte, comme ===. Arrivé dans la requête, $tri vaut forcément nom ou prix.

À retenir

À retenir :

  • Le diplôme décrit des compétences, pas un langage : les mêmes briques servent partout.
  • Python délimite les blocs par l'indentation, PHP et Java par les accolades.
  • En Java, 7 / 2 vaut 3 ; en Python et en PHP, 3.5.
  • Pour comparer deux textes : equals en Java, === en PHP.
  • Une saisie n'entre dans une requête SQL que par un marqueur, ou après contrôle contre une liste de valeurs permises.

Sources

  • Fiche RNCP 40792 du BTS « Services informatiques aux organisations », France compétences : francecompetences.fr.
  • Manuel PHP, opérateurs de comparaison : php.net.
  • Manuel PHP, requêtes préparées avec PDO : php.net.

Tu peux partager cette page librement, en citant ORBITECH AI Academy avec son lien.