Erreurs d'analyse / syntaxe PHP; et comment les résoudre

651

Tout le monde rencontre des erreurs de syntaxe. Même les programmeurs expérimentés font des fautes de frappe. Pour les nouveaux arrivants, cela fait simplement partie du processus d'apprentissage. Cependant, il est souvent facile d'interpréter des messages d'erreur tels que:

Erreur d'analyse PHP: erreur de syntaxe, '{' inattendu dans index.php à la ligne 20

Le symbole inattendu n'est pas toujours le vrai coupable. Mais le numéro de ligne donne une idée approximative de l'endroit où commencer la recherche.

Regardez toujours le contexte du code . L'erreur de syntaxe se cache souvent dans la mentionnée ou dans les lignes de code précédent . Comparez votre code avec des exemples de syntaxe du manuel.

Bien que tous les cas ne correspondent pas à l'autre. Pourtant, il existe quelques étapes générales pour résoudre les erreurs de syntaxe . Ces références résument les pièges courants:

Références étroitement liées:

Et:

Bien que Stack Overflow accueille également les codeurs débutants, il est principalement destiné aux questions de programmation professionnelle.

  • Répondre aux erreurs de codage et aux fautes de frappe de chacun est considéré comme hors sujet.
  • Veuillez donc prendre le temps de suivre les étapes de base , avant de publier des demandes de correction de syntaxe.
  • Si vous devez encore le faire, veuillez montrer votre propre initiative de résolution, les tentatives de correctifs et votre processus de réflexion sur ce qui semble ou pourrait être faux.

Si votre navigateur affiche des messages d'erreur tels que "SyntaxError: caractère illégal", alors ce n'est pas réellement-reliés, mais un - erreur de syntaxe .


Erreurs de syntaxe générées sur le code du fournisseur: Enfin, considérez que si l'erreur de syntaxe n'a pas été déclenchée en modifiant votre base de code, mais après une installation ou une mise à niveau d'un package de fournisseur externe, cela peut être dû à une incompatibilité de version PHP, alors vérifiez les exigences du fournisseur par rapport à votre plate-forme installer.

mario
la source
1
Ce n'est pas assez de données pour être une réponse, mais on pourrait écrire un analyseur avec parsekit_compile_string et y mettre des réponses plus conviviales. S'il est intégré à votre IDE, cela pourrait être très instructif.
Owen Beresford
4
Vous y avez consacré une quantité impressionnante de travail. Respect pour ça. Il est probablement très bon pour les enseignants d'apprendre à signaler rapidement les erreurs ou pour ceux qui créent des IDE ou implémentent des correctifs rapides. Cependant, les IDE feront déjà efficacement la plupart de ce travail pour vous, comme le suggère @Panique. De plus, dans de nombreux cas, recommencer à zéro est une bonne option.
allprog
1
@ Fred-ii- Je pense que la plupart des causes sont similaires au T_IF / T_FOREACH / ...bloc. Bien que je veuille compiler un résumé plus personnalisé pour les questions IF / ELSE / ELSEIF.
mario
1
@mario Je ne sais pas comment formuler cela, mais ce Q&R devrait-il être un peu réécrit et plus structuré? (commentaire temporaire)
Rizier123
2
Vous savez, j'aurais aimé avoir cette liste quand j'apprenais PHP il y a des années. Très utile, surtout pour les débutants.
Chipster

Réponses:

291

Quelles sont les erreurs de syntaxe?

PHP appartient aux langages de programmation de style C et impératifs . Il a des règles de grammaire rigides, qu'il ne peut pas récupérer lorsqu'il rencontre des symboles ou des identificateurs mal placés. Il ne peut pas deviner vos intentions de codage.

Résumé de la syntaxe de la définition de la fonction

Conseils les plus importants

Vous pouvez toujours prendre quelques précautions de base:

  • Utilisez une indentation de code appropriée ou adoptez un style de codage élevé. La lisibilité empêche les irrégularités.

  • Utilisez un IDE ou un éditeur pour PHP avec coloration syntaxique . Ce qui aide également à l'équilibrage des parenthèses / crochets.

    Attendu: point-virgule

  • Lisez la référence du langage et les exemples dans le manuel. Deux fois, pour devenir quelque peu compétent.

Comment interpréter les erreurs de l'analyseur

Un message d'erreur de syntaxe typique se lit comme suit:

Erreur d' analyse : erreur de syntaxe, T_STRING inattendu , attente de ' ;' dans file.php à la ligne 217

Qui répertorie l' emplacement possible d'une erreur de syntaxe. Voir le nom de fichier et le numéro de ligne mentionnés .

Un surnom tel queT_STRING qu'explique quel symbole l'analyseur / tokenizer n'a pas pu traiter finalement. Cependant, ce n'est pas nécessairement la cause de l'erreur de syntaxe.

Il est important d'examiner les lignes de code précédentes . Souvent, les erreurs de syntaxe ne sont que des incidents qui se sont produits plus tôt. Le numéro de la ligne d'erreur est l'endroit où l'analyseur a définitivement abandonné pour tout traiter.

Résolution des erreurs de syntaxe

Il existe de nombreuses approches pour réduire et corriger les hoquets de syntaxe.

  • Ouvrez le fichier source mentionné. Regardez la ligne de code mentionnée .

    • Pour les chaînes fugitives et les opérateurs mal placés, c'est généralement là que vous trouvez le coupable.

    • Lisez la ligne de gauche à droite et imaginez ce que fait chaque symbole.

  • Plus régulièrement, vous devez également consulter les lignes précédentes .

    • En particulier, les ;points-virgules manquants sont manquants à la fin de la ligne / instruction précédente. (Au moins du point de vue stylistique.)

    • Si les {blocs de code }sont mal fermés ou imbriqués, vous devrez peut-être enquêter encore plus haut sur le code source. Utilisez l' indentation de code appropriée pour simplifier cela.

  • Regardez la colorisation de la syntaxe !

    • Les chaînes, les variables et les constantes doivent toutes avoir des couleurs différentes.

    • Les opérateurs +-*/.doivent également être teintés. Sinon, ils pourraient être dans le mauvais contexte.

    • Si vous voyez la colorisation des chaînes s'étendre trop loin ou trop court, alors vous avez trouvé un marqueur de fermeture "ou de 'chaîne non échappé ou manquant .

    • Avoir deux caractères de ponctuation de même couleur l'un à côté de l'autre peut également signifier des problèmes. En général, les opérateurs sont isolés si ce n'est pas ++, --ou entre parenthèses après un opérateur. Deux chaînes / identificateurs se succédant directement sont incorrects dans la plupart des contextes.

  • Whitespace est votre ami . Suivez n'importe quel style de codage.

  • Coupez temporairement les longues files d'attente.

    • Vous pouvez librement ajouter des sauts de ligne entre opérateurs ou constantes et chaînes. L'analyseur concrétisera alors le numéro de ligne pour les erreurs d'analyse. Au lieu de regarder le code très long, vous pouvez isoler le symbole de syntaxe manquant ou mal placé.

    • Divisez les ifinstructions complexes en ifconditions distinctes ou imbriquées .

    • Au lieu de longues formules mathématiques ou de chaînes logiques, utilisez des variables temporaires pour simplifier le code. (Plus lisible = moins d'erreurs.)

    • Ajoutez des sauts de ligne entre:

      1. Le code que vous pouvez facilement identifier comme correct,
      2. Les pièces dont vous n'êtes pas sûr,
      3. Et les lignes dont l'analyseur se plaint.

      Le partitionnement de longs blocs de code aide vraiment à localiser l'origine des erreurs de syntaxe.

  • Commentez le code incriminé.

    • Si vous ne pouvez pas isoler la source du problème, commencez à commenter (et donc à supprimer temporairement) les blocs de code.

    • Dès que vous vous êtes débarrassé de l'erreur d'analyse, vous avez trouvé la source du problème. Regardez-y de plus près.

    • Parfois, vous souhaitez supprimer temporairement des blocs fonction / méthode complets. (En cas d'accolades et de code indenté indûment.)

    • Lorsque vous ne pouvez pas résoudre le problème de syntaxe, essayez de réécrire les sections mises en commentaire à partir de zéro .

  • En tant que nouveau venu, évitez certaines des constructions de syntaxe déroutantes.

    • L' ? :opérateur de condition ternaire peut compacter du code et est en effet utile. Mais cela ne facilite pas la lisibilité dans tous les cas. Préférez les ifdéclarations simples sans être inversé.

    • La syntaxe alternative de PHP ( if:/ elseif:/ endif;) est courante pour les modèles, mais sans doute moins facile à suivre que les blocs de {code normaux }.

  • Les erreurs de nouveaux arrivants les plus courantes sont:

    • Point-virgule manquant ;pour terminer les instructions / lignes.

    • Citations de chaîne incompatibles pour "ou 'et guillemets non échappés à l'intérieur.

    • Opérateurs oubliés, notamment pour la .concaténation de chaînes .

    • Déséquilibrées entre (parenthèses ). Comptez-les dans la ligne signalée. Y en a-t-il un nombre égal?

  • N'oubliez pas que la résolution d'un problème de syntaxe peut révéler le suivant.

    • Si vous faites disparaître un problème, mais que d'autres apparaissent dans un code ci-dessous, vous êtes principalement sur la bonne voie.

    • Si, après avoir modifié une nouvelle erreur de syntaxe, apparaît sur la même ligne, votre tentative de modification était probablement un échec. (Pas toujours cependant.)

  • Restaurez une sauvegarde du code fonctionnant précédemment, si vous ne pouvez pas le réparer.

    • Adoptez un système de versioning de code source. Vous pouvez toujours voir une diffde la dernière version de travail cassée. Ce qui pourrait éclairer sur le problème de syntaxe.
  • Caractères Unicode parasites invisibles : dans certains cas, vous devez utiliser un éditeur hexadécimal ou un éditeur / visualiseur différent sur votre source. Certains problèmes ne peuvent pas être trouvés simplement en regardant votre code.

    • Essayez grep --color -P -n "\[\x80-\xFF\]" file.phpcomme première mesure de trouver des symboles non ASCII.

    • En particulier, les nomenclatures, les espaces de largeur nulle ou les espaces insécables et les citations intelligentes peuvent régulièrement trouver leur chemin dans le code source.

  • Faites attention au type de saut de ligne enregistré dans les fichiers.

    • PHP ne fait qu'honorer les \nnouvelles lignes, pas \rles retours chariot.

    • Ce qui est parfois un problème pour les utilisateurs de MacOS (même sur OS X pour les éditeurs mal configurés).

    • Il n'apparaît souvent comme un problème que si une seule ligne //ou des #commentaires sont utilisés. Les /*...*/commentaires multilignes perturbent rarement l'analyseur lorsque les sauts de ligne sont ignorés.

  • Si votre erreur de syntaxe ne se transmet pas sur le Web : il se peut que vous ayez une erreur de syntaxe sur votre machine. Mais publier le même fichier en ligne ne l'expose plus. Ce qui ne peut signifier que deux choses:

    • Vous regardez le mauvais fichier!

    • Ou votre code contenait un Unicode errant invisible (voir ci-dessus). Vous pouvez facilement le découvrir: il vous suffit de recopier votre code du formulaire Web dans votre éditeur de texte.

  • Vérifiez votre version PHP . Toutes les constructions de syntaxe ne sont pas disponibles sur chaque serveur.

    • php -v pour l'interpréteur de ligne de commande

    • <?php phpinfo(); pour celui invoqué via le serveur Web.


    Ce ne sont pas nécessairement les mêmes. En particulier lorsque vous travaillez avec des frameworks, vous devrez les faire correspondre.

  • N'utilisez pas les mots clés réservés de PHP comme identificateurs pour les fonctions / méthodes, les classes ou les constantes.

  • Les essais et erreurs sont votre dernier recours.

Si tout le reste échoue, vous pouvez toujours google votre message d'erreur. Les symboles de syntaxe ne sont pas aussi faciles à rechercher (Stack Overflow lui-même est indexé par SymbolHound ). Par conséquent, il vous faudra peut-être parcourir quelques pages supplémentaires avant de trouver quelque chose de pertinent.

D'autres guides:

Écran blanc de la mort

Si votre site Web est juste vide, alors généralement une erreur de syntaxe en est la cause. Activez leur affichage avec:

  • error_reporting = E_ALL
  • display_errors = 1

Dans votre php.inigénéralement, ou via .htaccesspour mod_php, ou même.user.ini avec les configurations FastCGI.

L'activer dans le script cassé est trop tard car PHP ne peut même pas interpréter / exécuter la première ligne. Une solution rapide consiste à créer un script wrapper, par exemple test.php:

<?php
   error_reporting(E_ALL);
   ini_set("display_errors", 1);
   include("./broken-script.php");

Appelez ensuite le code défaillant en accédant à ce script wrapper.

Il permet également d'activer PHP error_loget de rechercher dans votre serveur Weberror.log lorsqu'un script se bloque avec des réponses HTTP 500.

mario
la source
error_reporting(E_ALL | E_STRICT);pour les versions antérieures de PHP
Geo
2
Certains IDE (comme NetBeans) prennent en charge non seulement la mise en évidence de la syntaxe mais également la mise en forme du code. Si vous prenez l'habitude de formater correctement votre code et de demander à l'EDI de reformater juste au cas où vous pourriez de temps en temps attraper des problèmes difficiles à repérer, comme des accolades inégalées.
Josep Valls
115

Je pense que ce sujet est totalement discuté / trop compliqué. L'utilisation d'un IDE est LA voie à suivre pour éviter complètement les erreurs de syntaxe. Je dirais même que travailler sans IDE n'est pas du tout professionnel. Pourquoi? Parce que les IDE modernes vérifient votre syntaxe après chaque caractère que vous tapez. Lorsque vous codez et que votre ligne entière devient rouge et qu'un gros avertissement vous indique le type exact et la position exacte de l'erreur de syntaxe, il n'est absolument pas nécessaire de rechercher une autre solution.

L'utilisation d'un IDE de vérification de syntaxe signifie:

Vous ne rencontrerez (effectivement) plus jamais d'erreurs de syntaxe, simplement parce que vous les voyez exactement lorsque vous tapez. Sérieusement.

Excellents IDE avec vérification de la syntaxe (tous sont disponibles pour Linux, Windows et Mac):

  1. NetBeans [gratuit]
  2. PHPStorm [199 $ USD]
  3. Eclipse avec PHP Plugin [gratuit]
  4. Sublime [80 $ USD] (principalement un éditeur de texte, mais extensible avec des plugins, comme PHP Syntax Parser )
Sliq
la source
2
C'est évidemment. Cependant, en réinscrivant les IDE ici, pouvez-vous élaborer un peu là où ils diffèrent par leur utilité syntaxique? Sublime est principalement un éditeur, pas IDE; mais alors plus joli et accrocheur; ne fait que mettre en évidence la syntaxe, mais est également un véritable outil de mise en correspondance des parenthèses. Il découvre facilement les erreurs T_CONSTANT_AND_ENCAPSED instantanément par exemple, contrairement à PHPStorm; qui fait cependant des lignes plus ondulées pour les erreurs en ligne. Les astuces de syntaxe de NetBeans étaient même plus cryptiques que les PHP (réinscrivant plutôt les constructions autorisées). Pouvez-vous partager votre expérience sur les avantages / inconvénients; est votre Eclipse / PDT préféré ou ..?
mario
@mario Je pense que vous êtes vraiment au fond du sujet, donc je ne veux vraiment rien dire de mal ici, mais tout le code que j'ai (et mes coéquipiers, amis qui codent, partenaires indépendants) ont déjà écrit dans un IDE n'a jamais été exécuté avec une erreur de syntaxe. Je pense donc qu'au moins la vérification de la syntaxe de Netbeans / PHPStorm est extrêmement puissante. Mais j'ai peut-être mal lu votre question. Donne
moi
Votre réponse est déjà exacte. Conviendrait à 99% de nos questions. Cependant, pour le contexte ici, je voudrais une considération de compromis sur laquelle l'IDE fournit les info-bulles les plus conviviales pour les débutants . C'est probablement mineur pour nous, la colorisation et les lignes ondulées étant suffisantes si vous êtes assez versé. Mais je suppose que les différences pourraient être plus importantes pour les débutants.
mario
Parfois, un IDE n'est pas une option réalisable. Par exemple, effectuer des modifications rapides sur un thème ou un plugin WordPress. Oui, je pourrais copier tout le code dans un IDE, mais je dois ensuite l'ouvrir, le coller tout dedans, définir des en-têtes et tout ce temps perdant de la merde, quand j'espère juste pour une modification rapide. Maintenant, si vous développez de nouvelles fonctionnalités ou recommencez à zéro, alors, oui, faites-le dans un IDE. Vous ne regretterez pas d'avoir pris ce peu de temps supplémentaire au début pour le configurer.
1934286
Je vois l'IDE comme une bande-annonce, pas seulement comme une boîte à outils. Ce n'est peut-être pas FIX mais cela peut vous aider à trouver et à prévenir les erreurs de syntaxe. Beaucoup de réponses ici semblent dire que si vous gardez votre code propre, vous avez moins de chance de faire une erreur et êtes plus facile à repérer. Eh bien, avec l'indentation automatique, les conseils de code, l'occurrence des variables, les crochets à fermeture automatique et le formatage automatique me font économiser de nombreuses fautes de frappe par jour et est le principal avantage pourquoi j'en utilise un. Cela ne compte pas tout le reste au-delà de la portée de cette question (débogueur, connecteur de base de données, diagramme uml, etc.) IDE vous fera gagner du temps et empêchera plus que de simples erreurs de syntaxe.
Louis Loudog Trottier
58

Inattendu [

Ces jours-ci, le [support de tableau inattendu est couramment utilisé sur les versions PHP obsolètes. La syntaxe du tableau court est disponible depuis PHP > = 5.4 . Les installations plus anciennes ne prennent en charge que array().

$php53 = array(1, 2, 3);
$php54 = [1, 2, 3];
         

Le déréférencement des résultats de la fonction de tableau n'est pas non plus disponible pour les anciennes versions de PHP:

$result = get_whatever()["key"];
                      

Référence - Que signifie cette erreur en PHP? - "Erreur de syntaxe, inattendue \[" affiche les solutions de contournement les plus courantes et pratiques.

Cependant, il vaut toujours mieux mettre à niveau votre installation PHP. Pour les plans d'hébergement Web partagés, commencez par rechercher si, par exemple, vous SetHandler php56-fcgipouvez utiliser pour activer un nouveau runtime.

Voir également:

BTW, il existe également des préprocesseurs et des convertisseurs de syntaxe PHP 5.4 si vous êtes vraiment collant avec les versions PHP plus anciennes + plus lentes.

Autres causes d' erreurs de syntaxe inattendues[

Si ce n'est pas la différence de version de PHP, c'est souvent une faute de frappe ou une erreur de syntaxe pour les nouveaux arrivants:

  • Vous ne pouvez pas utiliser les déclarations / expressions de propriété de tableau dans les classes , pas même en PHP 7.

    protected $var["x"] = "Nope";
                  
  • La confusion [avec l'ouverture des accolades {ou des parenthèses (est un oubli courant.

    foreach [$a as $b)
            

    Ou même:

    function foobar[$a, $b, $c] {
                   
  • Ou essayez de déréférencer les constantes (avant PHP 5.6) en tant que tableaux:

    $var = const[123];
           

    Au moins, PHP interprète cela constcomme un nom constant.

    Si vous vouliez accéder à une variable de tableau (ce qui est la cause typique ici), ajoutez le premier $sigil - il devient alors a $varname.

  • Vous essayez d'utiliser le globalmot clé sur un membre d'un tableau associatif. Ce n'est pas une syntaxe valide:

    global $var['key'];


Inattendue ] fermeture crochet

C'est un peu plus rare, mais il y a aussi des accidents de syntaxe avec le ]support de tableau de terminaison .

  • Encore une fois, les décalages avec des )parenthèses ou }des accolades sont courants:

    function foobar($a, $b, $c] {
                              
  • Ou essayez de terminer un tableau là où il n'y en a pas:

    $var = 2];

    Ce qui se produit souvent dans les déclarations de tableaux multilignes et imbriquées .

    $array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
                                                 

    Si tel est le cas, utilisez votre IDE pour la correspondance des parenthèses afin de trouver une ]fermeture prématurée de la baie. Utilisez au moins plus d'espacement et de nouvelles lignes pour le réduire.

mario
la source
Le lien «Convertisseurs abaisseurs de syntaxe PHP 5.4» github.com/IonutBajescu/short-arrays-to-long-arrays ci-dessus est rompu.
Danimal Reks
46

T_VARIABLE inattendu

Un "inattendu T_VARIABLE" signifie qu'il y a un $variablenom littéral , qui ne rentre pas dans la structure d'expression / instruction actuelle.

opérateur délibérément abstrait / inexact + diagramme variable $

  1. point-virgule manquant

    Il indique le plus souvent un point-virgule manquant sur la ligne précédente. Les affectations variables à la suite d'une instruction sont un bon indicateur où chercher:

           
    func1()
    $var = 1 + 2;     # parse error in line +2
  2. Concaténation de chaînes

    Les mésaventures fréquentes sont les concaténations de chaînes avec l' .opérateur oublié :

                                   
    print "Here comes the value: "  $value;

    Btw, vous devriez préférer l' interpolation de chaînes (variables de base entre guillemets) chaque fois que cela améliore la lisibilité. Ce qui évite ces problèmes de syntaxe.

    L'interpolation de chaînes est une fonctionnalité essentielle du langage de script . Pas de honte à l'utiliser. Ignorez tous les conseils de micro-optimisation pour que la .concaténation des variables soit plus rapide . Ce n'est pas.

  3. Opérateurs d'expression manquants

    Bien sûr, le même problème peut survenir dans d'autres expressions, par exemple les opérations arithmétiques:

               
    print 4 + 7 $var;

    PHP ne peut pas deviner ici si la variable aurait dû être ajoutée, soustraite ou comparée, etc.

  4. Listes

    Idem pour les listes de syntaxe, comme dans les populations de tableaux, où l'analyseur indique également une virgule attendue, ,par exemple:

                                          
    $var = array("1" => $val, $val2, $val3 $val4);

    Ou listes de paramètres de fonctions:

                                    
    function myfunc($param1, $param2 $param3, $param4)

    De manière équivalente voyez-vous cela avec des instructions listou global, ou en l'absence d'un ;point - virgule dans une forboucle.

  5. Déclarations de classe

    Cette erreur de l'analyseur se produit également dans les déclarations de classe . Vous ne pouvez affecter que des constantes statiques, pas des expressions. Ainsi, l'analyseur se plaint des variables en tant que données affectées:

    class xyz {      
        var $value = $_GET["input"];

    Des }accolades fermantes inégalées peuvent notamment conduire ici. Si une méthode est terminée trop tôt (utilisez une indentation appropriée!), Une variable parasite est généralement mal placée dans le corps de déclaration de classe.

  6. Variables après les identifiants

    Vous ne pouvez jamais non plus qu'une variable suive directement un identifiant :

                 
    $this->myFunc$VAR();

    En fait, c'est un exemple courant où l'intention était peut-être d'utiliser des variables variables . Dans ce cas une recherche de propriété variable avec $this->{"myFunc$VAR"}();par exemple.

    Gardez à l'esprit que l'utilisation de variables variables devrait être l'exception. Les nouveaux arrivants essaient souvent de les utiliser de manière trop désinvolte, même lorsque les tableaux seraient plus simples et plus appropriés.

  7. Parenthèses manquantes après les constructions de langage

    Hasty frappe peut entraîner une parenthèse ouverte ou fermée oublié pour ifet foret foreachdéclarations:

           
    foreach $array as $key) {

    Solution: ajoutez l'ouverture manquante (entre l'instruction et la variable.

                          
    if ($var = pdo_query($sql) {
         $result = 

    L' {accolade n'ouvre pas le bloc de code sans fermer d'abord l' ifexpression avec la )parenthèse fermante.

  8. Sinon, ne s'attend pas à des conditions

         
    else ($var >= 0)

    Solution: supprimez les conditions elseou utilisez-les elseif.

  9. Besoin de supports pour la fermeture

         
    function() uses $var {}

    Solution: ajoutez des crochets autour $var.

  10. Espace blanc invisible

    Comme mentionné dans la réponse de référence sur "Unicode errant invisible" (comme un espace insécable ), vous pouvez également voir cette erreur pour un code sans méfiance comme:

    <?php
                              
    $var = new PDO(...);

    C'est plutôt répandu au début des fichiers et pour le code copié-collé. Vérifiez avec un hexeditor, si votre code ne semble pas visuellement contenir un problème de syntaxe.

Voir également

mario
la source
32

T_CONSTANT_ENCAPSED_STRING
inattendu T_ENCAPSED_AND_WHITESPACE inattendu

Les noms lourds T_CONSTANT_ENCAPSED_STRINGet se T_ENCAPSED_AND_WHITESPACEréfèrent aux littéraux cités ."string"

Ils sont utilisés dans différents contextes, mais le problème de syntaxe est assez similaire. Les avertissements T_ENCAPSED… se produisent dans un contexte de chaîne entre guillemets doubles, tandis que les chaînes T_CONSTANT… sont souvent égarées dans des expressions ou des instructions PHP simples.

  1. Interpolation de variable incorrecte

    Et cela revient le plus souvent pour une interpolation de variable PHP incorrecte:

                                   
    echo "Here comes a $wrong['array'] access";

    La citation des clés de tableaux est un must dans le contexte PHP. Mais dans les chaînes entre guillemets doubles (ou HEREDOC), c'est une erreur. L'analyseur se plaint du single contenu entre guillemets 'string', car il y attend généralement un identifiant / clé littéral.

    Plus précisément, il est valide d'utiliser la syntaxe simple de style PHP2 entre guillemets doubles pour les références de tableau:

    echo "This is only $valid[here] ...";

    Les tableaux imbriqués ou les références d'objets plus profondes nécessitent cependant la syntaxe d' expression de chaîne bouclée complexe :

    echo "Use {$array['as_usual']} with curly syntax.";

    En cas de doute, cela est généralement plus sûr à utiliser. Il est même souvent considéré comme plus lisible. Et les meilleurs IDE utilisent en fait une colorisation de syntaxe distincte pour cela.

  2. Concaténation manquante

    Si une chaîne suit une expression, mais manque une concaténation ou un autre opérateur, alors vous verrez PHP se plaindre du littéral de la chaîne:

                           
    print "Hello " . WORLD  " !";

    Bien que cela soit évident pour vous et pour moi, PHP ne peut tout simplement pas deviner que la chaîne était censée y être ajoutée.

  3. Boîtes de guillemets déroutantes

    La même erreur de syntaxe se produit lors de la confusion des délimiteurs de chaîne . Une chaîne commencée par un guillemet simple 'ou double "se termine également par le même.

                    
    print "<a href="' . $link . '">click here</a>";
          ⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟

    Cet exemple a commencé par des guillemets doubles. Mais les guillemets doubles étaient également destinés aux attributs HTML. L'opérateur de concaténation prévu à l'intérieur est toutefois devenu interprété comme faisant partie d'une deuxième chaîne entre guillemets simples.

    Astuce : définissez votre éditeur / IDE pour utiliser une colorisation légèrement distincte pour les chaînes entre guillemets simples et doubles. (Cela aide également la logique d'application à préférer, par exemple, les chaînes entre guillemets doubles pour la sortie textuelle et les chaînes entre guillemets simples uniquement pour les valeurs de type constant.)

    Ceci est un bon exemple où vous ne devriez pas sortir des guillemets doubles en premier lieu. Utilisez plutôt des \"échappements appropriés pour les guillemets des attributs HTML:

    print "<a href=\"{$link}\">click here</a>";

    Bien que cela puisse également entraîner une confusion de syntaxe, tous les meilleurs IDE / éditeurs aident à nouveau en colorisant différemment les guillemets échappés.

  4. Citation d'ouverture manquante

    De manière équivalente sont oubliés l'ouverture "/ 'cite une recette pour les erreurs de l'analyseur:

                   
     make_url(login', 'open');

    Ici, le ', 'deviendrait un littéral de chaîne après un mot nu, alors qu'il loginétait évidemment censé être un paramètre de chaîne.

  5. Listes de tableaux

    Si vous manquez une ,virgule dans un bloc de création de tableau, l'analyseur verra deux chaînes consécutives:

    array(               
         "key" => "value"
         "next" => "....",
    );

    Notez que la dernière ligne peut toujours contenir une virgule supplémentaire, mais en ignorer une entre les deux est impardonnable. Ce qui est difficile à découvrir sans mise en évidence de la syntaxe.

  6. Listes des paramètres de fonction

    La même chose pour les appels de fonction :

                             
    myfunc(123, "text", "and"  "more")
  7. Cordes fugitives

    Une variante courante est tout simplement les terminateurs de chaîne oubliés:

                                    
    mysql_evil("SELECT * FROM stuffs);
    print "'ok'";
          ⇑

    Ici, PHP se plaint de deux littéraux de chaîne qui se suivent directement. Mais la vraie cause est bien sûr la chaîne précédente non fermée.

Voir également

mario
la source
27

T_STRING inattendu

T_STRINGest un peu impropre. Il ne fait pas référence à un cité "string". Cela signifie qu'un identifiant brut a été rencontré. Cela peut aller des baremots aux restes CONSTANTou aux noms de fonctions, aux chaînes non citées ou à tout texte brut.

  1. Chaînes mal citées

    Cette erreur de syntaxe est cependant plus courante pour les valeurs de chaîne mal citées. Tout échappé et errant "ou 'citation formera une expression invalide:

                                     
     echo "<a href="http://example.com">click here</a>";

    La mise en évidence de la syntaxe rendra ces erreurs super évidentes. Il est important de se rappeler d'utiliser des barres obliques inverses pour s'échapper\" guillemets doubles ou \'simples - selon ce qui a été utilisé comme enceinte de chaîne .

    • Pour plus de commodité, vous devriez préférer les guillemets simples externes lors de la sortie de HTML simple avec des guillemets doubles.
    • Utilisez des chaînes entre guillemets doubles si vous voulez interpoler des variables, mais faites attention aux échappements littéraux " guillemets .
    • Pour une sortie plus longue, préférez plusieurs echo/ printlignes au lieu de vous échapper. Mieux vaut envisager un HEREDOC section .

    Un autre exemple utilise l'entrée PHP dans le code HTML généré avec PHP:

    $text = '<div>some text with <?php echo 'some php entry' ?></div>'

    Cela se produit si $textest grand avec de nombreuses lignes et que le développeur ne voit pas toute la valeur de la variable PHP et se concentre sur le morceau de code en oubliant sa source. L'exemple est ici

    Voir aussi Quelle est la différence entre les chaînes entre guillemets simples et entre guillemets doubles en PHP? .

  2. Chaînes non fermées

    Si vous manquez une fermeture," une erreur de syntaxe se produit généralement plus tard. Une chaîne non terminée consommera souvent un peu de code jusqu'à la prochaine valeur de chaîne prévue:

                                                           
    echo "Some text", $a_variable, "and some runaway string ;
    success("finished");
             ⇯

    Ce ne sont pas seulement les littéraux T_STRINGque l'analyseur peut alors protester. Une autre variation fréquente est celle Unexpected '>'du HTML littéral non cité.

  3. Citations de chaîne sans programmation

    Si vous copiez et collez du code à partir d'un blog ou d'un site Web, vous vous retrouvez parfois avec un code non valide. PHP n'est pas ce à quoi s'attend PHP:

    $text = Something something..’ + these ain't quotes”;

    Les citations typographiques / intelligentes sont des symboles Unicode. PHP les traite comme faisant partie du texte alphanumérique adjacent. Par exemple, ”theseest interprété comme un identifiant constant. Mais tout littéral de texte suivant est alors vu comme un bareword / T_STRING par l'analyseur.

  4. Le point-virgule manquant; encore

    Si vous avez une expression non terminée dans les lignes précédentes, toute instruction ou construction de langage suivante est considérée comme un identifiant brut:

           
    func1()
    function2();

    PHP ne peut tout simplement pas savoir si vous vouliez exécuter deux fonctions l'une après l'autre, ou si vous vouliez multiplier leurs résultats, les ajouter, les comparer ou exécuter uniquement l'une ||ou l'autre.

  5. Balises ouvertes courtes et <?xml têtes dans les scripts PHP

    C'est assez rare. Mais si short_open_tags sont activés, vous ne pouvez pas commencer vos scripts PHP avec une déclaration XML :

          
    <?xml version="1.0"?>

    PHP le verra <?et le récupérera pour lui-même. Il ne comprendra pas à quoi xmlétait destiné le parasite . Il sera interprété comme constant. Mais le versionsera considéré comme un autre littéral / constant. Et puisque l'analyseur ne peut pas comprendre deux littéraux / valeurs subséquents sans opérateur d'expression entre les deux, ce sera un échec de l'analyseur.

  6. Caractères Unicode invisibles

    Les symboles Unicode, tels que l' espace insécable , sont la cause la plus hideuse des erreurs de syntaxe . PHP autorise les caractères Unicode comme noms d'identifiants. Si vous recevez une réclamation de l'analyseur T_STRING pour un code totalement suspect, comme:

    <?php
        print 123;

    Vous devez sortir un autre éditeur de texte. Ou même un hexeditor. Ce qui ressemble à des espaces simples et à des retours à la ligne ici, peut contenir des constantes invisibles. Les IDE basés sur Java sont parfois inconscients d'une nomenclature UTF-8 modifiée à l'intérieur, d'espaces de largeur nulle, de séparateurs de paragraphes, etc. Essayez de tout rééditer, de supprimer les espaces et d'ajouter des espaces normaux.

    Vous pouvez l'affiner avec l'ajout de ;séparateurs d'instruction redondants à chaque début de ligne:

    <?php
        ;print 123;

    Le ;point-virgule supplémentaire ici convertira le caractère invisible précédent en une référence constante non définie (expression en tant qu'instruction). En retour, PHP produit un avis utile.

  7. Le signe `$` manque devant les noms de variables

    Les variables en PHP sont représentées par un signe dollar suivi du nom de la variable.

    Le signe dollar ( $) est un sceau qui marque l'identifiant comme nom d'une variable. Sans ce sceau, l'identifiant pourrait être un mot - clé de langue ou une constante .

    Il s'agit d'une erreur courante lorsque le code PHP a été "traduit" à partir de code écrit dans un autre langage (C, Java, JavaScript, etc.). Dans de tels cas, une déclaration du type de variable (lorsque le code d'origine a été écrit dans un langage qui utilise des variables typées) peut également se faufiler et produire cette erreur.

  8. Guillemets échappés

    Si vous utilisez \une chaîne, elle a une signification particulière. Cela s'appelle un " caractère d'échappement " et indique normalement à l'analyseur de prendre le caractère suivant littéralement.

    Exemple: echo 'Jim said \'Hello\'';imprimeraJim said 'hello'

    Si vous échappez à la citation de fermeture d'une chaîne, la citation de fermeture sera prise littéralement et non comme prévu, c'est-à-dire comme une citation imprimable dans le cadre de la chaîne et ne fermera pas la chaîne. Cela apparaîtra comme une erreur d'analyse couramment après avoir ouvert la chaîne suivante ou à la fin du script.

    Erreur très courante lors de la spécification de chemins dans Windows: "C:\xampp\htdocs\"est incorrect. Vous en avez besoin "C:\\xampp\\htdocs\\".

mario
la source
18

Inattendu (

Les parenthèses ouvrantes suivent généralement des constructions de langage telles que if/ foreach/ for/ array/ listou démarrent une expression arithmétique. Ils sont syntaxiquement incorrects après "strings", un précédent (), un seul $et dans certains contextes de déclaration typiques.

  1. Paramètres de déclaration de fonction

    Une occurrence plus rare de cette erreur consiste à utiliser des expressions comme paramètres de fonction par défaut . Ceci n'est pas pris en charge, même en PHP7:

    function header_fallback($value, $expires = time() + 90000) {

    Les paramètres d'une déclaration de fonction ne peuvent être que des valeurs littérales ou des expressions constantes. Contrairement aux appels de fonctions, où vous pouvez utiliser librement whatever(1+something()*2), etc.

  2. Valeurs par défaut des propriétés de classe

    Même chose pour les déclarations des membres de classe , où seules les valeurs littérales / constantes sont autorisées, pas les expressions:

    class xyz {                   
        var $default = get_config("xyz_default");

    Mettez de telles choses dans le constructeur. Voir aussi Pourquoi les attributs PHP n'autorisent-ils pas les fonctions?

    Notez à nouveau que PHP 7 ne permet que var $xy = 1 + 2 +3;des expressions constantes.

  3. Syntaxe JavaScript en PHP

    L'utilisation de la syntaxe JavaScript ou jQuery ne fonctionnera pas en PHP pour des raisons évidentes:

    <?php      
        print $(document).text();

    Lorsque cela se produit, cela indique généralement une chaîne précédente non terminée; et les <script>sections littérales s'infiltrant dans le contexte du code PHP.

  4. isset (()), vide, clé, suivant, actuel

    Les deux isset()et empty()sont la langue Encastrements, pas de fonctions. Ils doivent accéder directement à une variable . Si vous ajoutez trop de parenthèses par inadvertance, vous créerez cependant une expression:

              
    if (isset(($_GET["id"]))) {

    La même chose s'applique à toute construction de langage qui nécessite un accès implicite au nom de variable. Ces éléments intégrés font partie de la grammaire du langage, donc ne permettent pas de parenthèses décoratives supplémentaires.

    Les fonctions de niveau utilisateur qui nécessitent une référence de variable -mais obtenir un résultat d'expression passé- conduisent à la place à des erreurs d'exécution.


Inattendu )

  1. Paramètre de fonction absent

    Vous ne pouvez pas avoir de virgules errantes en dernier dans un appel de fonction . PHP attend une valeur là-bas et se plaint donc d'une )parenthèse de fermeture anticipée .

                  
    callfunc(1, 2, );

    Une virgule de fin n'est autorisée que dans array()ou se list()construit.

  2. Expressions inachevées

    Si vous oubliez quelque chose dans une expression arithmétique, alors l'analyseur abandonne. Parce que comment devrait-il éventuellement interpréter cela:

                   
    $var = 2 * (1 + );

    Et si vous oubliez même la fermeture ), vous obtiendrez alors une plainte concernant le point-virgule inattendu.

  3. Foreach as constant

    Pour les $préfixes de variable oubliés dans les instructions de contrôle, vous verrez:

                           
    foreach ($array as wrong) {

    PHP ici vous dit parfois qu'il s'attendait à une ::place. Parce qu'une variable class :: $ aurait pu satisfaire l'expression $ variable attendue.


Inattendu {

Accolades {et }entourez les blocs de code. Et les erreurs de syntaxe à leur sujet indiquent généralement une imbrication incorrecte.

  1. Sous-expressions inégalées dans un if

    Le plus souvent déséquilibré (et) sont la cause si l'analyseur se plaint de l'ouverture bouclée {apparaissant trop tôt. Un exemple simple:

                                  
    if (($x == $y) && (2 == true) {

    Comptez vos parenthèses ou utilisez un IDE qui vous aide. N'écrivez pas non plus de code sans espaces. La lisibilité compte.

  2. {et} dans le contexte de l'expression

    Vous ne pouvez pas utiliser d'accolades dans les expressions. Si vous confondez parenthèses et curlys, cela ne sera pas conforme à la grammaire de la langue:

               
    $var = 5 * {7 + $x};

    Il existe quelques exceptions pour la construction de l'identificateur, comme la variable de portée locale ${references}.

  3. Variables variables ou expressions var bouclées

    C'est assez rare. Mais vous pouvez également obtenir {et }analyser des plaintes pour des expressions de variables complexes:

                          
    print "Hello {$world[2{]} !";

    Bien qu'il y ait une probabilité plus élevée d'inattendu }dans de tels contextes.


Inattendu }

Lorsque vous obtenez une }erreur "inattendue ", vous avez généralement fermé un bloc de code trop tôt.

  1. Dernière instruction dans un bloc de code

    Cela peut arriver pour toute expression non terminée.

    Et si la dernière ligne d'un bloc fonction / code n'a pas de ;point-virgule de fin :

    function whatever() {
        doStuff()
    }            

    Ici, l'analyseur ne peut pas dire si vous vouliez peut-être encore ajouter + 25;au résultat de la fonction ou autre chose.

  2. Imbrication de bloc invalide / Oubliée {

    Vous verrez parfois cette erreur de l'analyseur lorsqu'un bloc de code a été }fermé trop tôt, ou vous avez même oublié une ouverture {:

    function doStuff() {
        if (true)    
            print "yes";
        }
    }   

    Dans l'extrait ci-dessus, le corset ifn'avait pas d'ouverture {. Ainsi, la clôture }ci-dessous est devenue superflue. Et donc la prochaine fermeture }, qui était destinée à la fonction, n'était pas associable à l' {accolade ouvrante d'origine .

    De telles erreurs sont encore plus difficiles à trouver sans retrait correct du code. Utilisez un IDE et une correspondance de parenthèses.


Inattendu {, attend(

Les constructions de langage qui nécessitent un en-tête de condition / déclaration et un bloc de code déclencheront cette erreur.

  1. Listes de paramètres

    Par exemple, les fonctions mal déclarées sans liste de paramètres ne sont pas autorisées:

                     
    function whatever {
    }
  2. Conditions de l'énoncé de contrôle

    Et vous ne pouvez pas non plus avoir une ifcondition sans .

      
    if {
    }

    Ce qui n'a pas de sens, évidemment. La même chose pour les suspects habituels, for/ foreach, while/ do, etc.

    Si vous avez cette erreur particulière, vous devriez certainement rechercher des exemples manuels.

mario
la source
1
Je cherchais une réponse à ma question dans cet article, mais j'ai trouvé moi-même une réponse au problème de "" inattendu {", c'est pourquoi je voulais partager avec ma réponse - pour moi, le problème était l'encodage par saut de ligne - en quelque sorte certains de mes les fichiers utilisaient des sauts de ligne macintosh, mais quand je les ai changés en sauts de ligne Windows - mon problème (sur localhost (WAMP) tout fonctionne, mais sur le serveur web linux pas) a été résolu.
Edgars Aivars
@EdgarsAivars Merci pour votre commentaire! Les sauts de ligne spécifiques à la plate-forme sont en effet un problème rare et délicat. Je vais probablement le mentionner ici aussi. (Il a juste été mentionné comme mis de côté dans l' autre réponse de référence .)
mario
J'ai trouvé qu'obtenir inattendu} était dû au fait qu'un morceau de mon code utilisait la balise php short <? au lieu de <? php - il m'a fallu un certain temps pour trouver celui-ci car il fonctionnait sur d'autres serveurs.
c7borg
14

$ End inattendu

Lorsque PHP parle d'un "inattendu $end", cela signifie que votre code s'est terminé prématurément. (Le message est un peu trompeur lorsqu'il est pris à la lettre. Il ne s'agit pas d'une variable nommée "$ end", comme le supposent parfois les nouveaux arrivants. Il fait référence à la "fin du fichier",. EOF)

Cause: asymétrique {et }pour les blocs de code / et les déclarations de fonctions ou de classes.

Il s'agit presque toujours d'une }accolade manquante pour fermer les blocs de code précédents.

  • Encore une fois, utilisez une indentation appropriée pour éviter de tels problèmes.

  • Utilisez un IDE avec correspondance des parenthèses pour savoir où cela }ne va pas. Il existe des raccourcis clavier dans la plupart des IDE et des éditeurs de texte:

    • NetBeans, PhpStorm, Komodo: Ctrl[etCtrl]
    • Eclipse, Aptana: CtrlShiftP
    • Atom, Sublime: Ctrlm- Zend StudioCtrlM
    • Geany, Bloc-notes ++: CtrlB- Joe: CtrlG- Emacs: C-M-n- Vim:%

La plupart des IDE mettent également en évidence les accolades, crochets et parenthèses correspondants. Ce qui facilite l'inspection de leur corrélation:

Correspondance entre parenthèses dans un IDE

Expressions non terminées

Et Unexpected $endune erreur de syntaxe / analyseur peut également se produire pour les expressions ou instructions non terminées:

  • $var = func(1, ?>EOF

Alors, regardez d'abord la fin des scripts. Une fin ;est souvent redondante pour la dernière instruction de n'importe quel script PHP. Mais vous devriez en avoir un. Précisément parce qu'il réduit ces problèmes de syntaxe.

Marqueurs HEREDOC en retrait

Un autre phénomène courant apparaît avec les chaînes HEREDOC ou NOWDOC . Le marqueur de fin est ignoré avec les espaces, les tabulations, etc.:

print <<< END
    Content...
    Content....
  END;
# ↑ terminator isn't exactly at the line start

Par conséquent, l'analyseur suppose que la chaîne HEREDOC se poursuit jusqu'à la fin du fichier (d'où "Fin $ inattendue"). Presque tous les IDE et les éditeurs de coloration syntaxique le rendront évident ou en avertiront.

Guillemets échappés

Si vous utilisez \une chaîne, elle a une signification particulière. Cela s'appelle un " caractère d'échappement " et indique normalement à l'analyseur de prendre le caractère suivant littéralement.

Exemple: echo 'Jim said \'Hello\'';imprimeraJim said 'hello'

Si vous échappez à la citation de fermeture d'une chaîne, la citation de fermeture sera prise littéralement et non comme prévu, c'est-à-dire comme une citation imprimable dans le cadre de la chaîne et ne fermera pas la chaîne. Cela apparaîtra comme une erreur d'analyse couramment après avoir ouvert la chaîne suivante ou à la fin du script.

Erreur très courante lors de la spécification de chemins dans Windows: "C:\xampp\htdocs\"est incorrect. Vous en avez besoin "C:\\xampp\\htdocs\\".

Syntaxe alternative

Un peu plus rare, vous pouvez voir cette erreur de syntaxe lors de l'utilisation de la syntaxe alternative pour les blocs d'instructions / de code dans les modèles. Utiliser if:et else:et un manquant endif;par exemple.

Voir également:

mario
la source
14

T_IF
inattendu T_ELSEIF
inattendu T_ELSE
inattendu T_ENDIF inattendu

Blocs de contrôle conditionnels if, elseifet elsesuivez une structure simple. Lorsque vous rencontrez une erreur de syntaxe, il s'agit très probablement d'une imbrication de blocs non valide → avec des {accolades manquantes }- ou une de trop.

entrez la description de l'image ici

  1. Manquant {ou }dû à une indentation incorrecte

    Les accolades de code incompatibles sont communes aux codes moins bien formatés tels que:

    if((!($opt["uniQartz5.8"]!=$this->check58)) or (empty($_POST['poree']))) {if
    ($true) {echo"halp";} elseif((!$z)or%b){excSmthng(False,5.8)}elseif (False){

    Si votre code ressemble à ceci, recommencez! Sinon, cela ne peut pas être résolu pour vous ou quelqu'un d'autre. Il est inutile de présenter cela sur Internet pour demander de l'aide.

    Vous ne pourrez y remédier que si vous pouvez suivre visuellement la structure et la relation imbriquées des conditionnelles if / else et de leurs {blocs de code }. Utilisez votre IDE pour voir s'ils sont tous appariés.

    if (true) {
         if (false) {
                  
         }
         elseif ($whatever) {
             if ($something2) {
                 
             } 
             else {
                 
             }
         }
         else {
             
         }
         if (false) {    //   a second `if` tree
             
         }
         else {
             
         }
    }
    elseif (false) {
        
    }

    Tout double } }ne fermera pas seulement une branche, mais une structure de condition précédente. Par conséquent, respectez un seul style de codage; ne pas mélanger et assortir dans les arbres imbriqués if / else.

    En dehors de la cohérence ici, il s'avère utile d'éviter également les longues conditions. Utilisez des variables ou des fonctions temporaires pour éviter les ifexpressions illisibles .

  2. IF ne peut pas être utilisé dans les expressions

    Une erreur de nouveau venu étonnamment fréquente essaie d'utiliser une ifdéclaration dans une expression, telle qu'une déclaration imprimée:

                       
    echo "<a href='" . if ($link == "example.org") { echo 

    Ce qui n'est pas valable bien sûr.

    Vous pouvez utiliser un conditionnel ternaire , mais méfiez-vous des impacts sur la lisibilité.

    echo "<a href='" . ($link ? "http://yes" : "http://no") . "</a>";

    Sinon, cassez ces constructions de sortie: utilisez plusieurs ifs et echos .
    Mieux encore, utilisez des variables temporaires et placez vos conditionnelles avant:

    if ($link) { $href = "yes"; } else { $href = "no"; }
    echo "<a href='$href'>Link</a>";

    La définition de fonctions ou de méthodes pour de tels cas est également souvent logique.

    Les blocs de contrôle ne renvoient pas de "résultats"

    Maintenant, c'est moins courant, mais quelques codeurs essaient même de traiter ifcomme si cela pouvait retourner un résultat :

    $var = if ($x == $y) { "true" };

    Ce qui est structurellement identique à l'utilisation ifdans une concaténation / expression de chaîne.

    • Mais les structures de contrôle (si / foreach / while) n'ont pas de "résultat" .
    • La chaîne littérale "true" ne serait également qu'une déclaration void.

    Vous devrez utiliser une affectation dans le bloc de code :

    if ($x == $y) { $var = "true"; }

    Alternativement, recourir à une ?:comparaison ternaire.

    Si dans If

    Vous ne pouvez pas non plus imbriquer uneif condition dans une condition:

                        
    if ($x == true and (if $y != false)) { ... }

    Ce qui est évidemment redondant, car le and(ou or) permet déjà de chaîner des comparaisons.

  3. Points- ;virgules oubliés

    Encore une fois: chaque bloc de contrôle doit être une instruction. Si le morceau de code précédent n'est pas terminé par un point-virgule, c'est une erreur de syntaxe garantie:

                    
    $var = 1 + 2 + 3
    if (true) {  }

    Btw, la dernière ligne d'un {…}bloc de code a également besoin d'un point-virgule.

  4. Point-virgule trop tôt

    Maintenant, il est probablement faux de blâmer un style de codage particulier, car cet écueil est trop facile à ignorer:

                
    if ($x == 5);
    {
        $y = 7;
    }
    else           
    {
        $x = -1;    
    }

    Ce qui se produit plus souvent que vous ne l'imaginez.

    • Lorsque vous terminez l' if ()expression avec,; elle exécutera une instruction void. Le ;devient un vide en {}soi!
    • Le {…}bloc est ainsi détaché du if, et fonctionnerait toujours.
    • Donc, le elsen'avait plus de relation avec une ifconstruction ouverte , c'est pourquoi cela conduirait à une erreur de syntaxe T_ELSE inattendue.

    Ce qui explique également une variation également subtile de cette erreur de syntaxe:

    if ($x) { x_is_true(); }; else { something_else(); };

    ;après le bloc de code {…}termine la if construction entière , coupant la elsebranche syntaxiquement.

  5. Ne pas utiliser de blocs de code

    Il est syntaxiquement autorisé d'omettre les accolades {}pour les blocs de code dans if/ elseif/ elsebranches. Ce qui est malheureusement un style de syntaxe très commun aux codeurs non inversés. (Sous l'hypothèse fausse, c'était plus rapide à taper ou à lire).

    Cependant, cela est très susceptible de déclencher la syntaxe. Tôt ou tard, des instructions supplémentaires trouveront leur chemin dans les branches if / else:

    if (true)
        $x = 5;
    elseif (false)
        $x = 6;
        $y = 7;     
    else
        $z = 0;

    Mais pour réellement utiliser des blocs de code, vous devez les écrire {}tels quels!

    Même les programmeurs chevronnés évitent cette syntaxe sans bretelles, ou du moins la comprennent comme une exception exceptionnelle à la règle.

  6. Sinon / Elseif dans le mauvais ordre

    Une chose à vous rappeler est bien sûr l' ordre conditionnel .

    if ($a) {  }
    else {  }
    elseif ($b) {  }
    

    Vous pouvez avoir autant de elseifs que vous le souhaitez, mais cela elsedoit durer . C'est comme ça.

  7. Déclarations de classe

    Comme mentionné ci-dessus , vous ne pouvez pas avoir d'instructions de contrôle dans une déclaration de classe:

    class xyz {
        if (true) {
            function ($var) {}
        }

    Vous avez soit oublié une définition de fonction , soit fermé }trop tôt dans de tels cas.

  8. T_ELSEIF / T_ELSE inattendu

    Lors du mélange de PHP et HTML, la fermeture }d'un if/elseifdoit être dans le même bloc PHP <?php ?>que le suivant elseif/else. Cela générera une erreur car la fermeture }des ifbesoins doit faire partie de elseif:

    <?php if ($x) { ?>
        html
    <?php } ?>
    <?php elseif ($y) { ?>
        html
    <?php } ?>

    La forme correcte <?php } elseif:

    <?php if ($x) { ?>
        html
    <?php } elseif ($y) { ?>
        html
    <?php } ?>

    Il s'agit plus ou moins d'une variation d'indentation incorrecte - vraisemblablement souvent basée sur de mauvaises intentions de codage.
    Vous ne pouvez pas écraser d'autres instructions entre les jetons ifet elseif/ elsestructurels:

    if (true) {
    }
    echo "in between";    
    elseif (false) {
    }
    ?> text <?php      
    else {
    }

    L'un ou l'autre ne peut se produire que dans {…}des blocs de code, pas entre des jetons de structure de contrôle.

    • Cela n'aurait aucun sens de toute façon. Ce n'est pas comme s'il y avait un état "indéfini" lorsque PHP saute entre les branches ifet else.
    • Vous devrez décider où les instructions d'impression appartiennent à / ou si elles doivent être répétées dans les deux branches.

    Vous ne pouvez pas non plus séparer un if / else entre différentes structures de contrôle:

    foreach ($array as $i) {
        if ($i) {  }
    }
    else {  }

    Il n'y a pas de relation syntaxique entre le ifet else. La foreachportée lexicale se termine à }, il n'y a donc aucun intérêt pour la ifstructure de continuer.

  9. T_ENDIF

    Si un T_ENDIF inattendu est signalé, vous utilisez l'autre style de syntaxe if:elseif:else:endif;. Ce à quoi vous devriez vraiment réfléchir à deux fois.

    • Un piège commun confond le côlon étrangement similaire :pour un ;point - virgule . (Couvert dans "Point-virgule trop tôt")

    • Comme l'indentation est plus difficile à suivre dans les fichiers de modèle, plus lorsque vous utilisez la syntaxe alternative - il est plausible que votre endif;ne corresponde à aucune if:.

    • L'utilisation } endif; est un double if terminateur.

    Alors qu'une "fin $ inattendue" est généralement le prix d'une }accolade fermante oubliée .

  10. Affectation vs comparaison

    Donc, ce n'est pas une erreur de syntaxe, mais mérite d'être mentionnée dans ce contexte:

           
    if ($x = true) { }
    else { do_false(); }

    Ce n'est pas une comparaison ==/ ===, mais une =affectation . Ceci est plutôt subtil et conduira facilement certains utilisateurs à éditer en toute impuissance des blocs de condition entiers. Méfiez-vous d'abord des affectations involontaires - chaque fois que vous rencontrez un défaut / mauvais comportement logique.

mario
la source
11

Inattendu T_IS_EQUAL
Inattendu T_IS_GREATER_OR_EQUAL
Inattendu T_IS_IDENTICAL
Inattendu T_IS_NOT_EQUAL
Inattendu T_IS_NOT_IDENTICAL
Inattendu T_IS_SMALLER_OR_EQUAL
Inattendu <
Inattendu>

Les opérateurs de comparaison tels que ==, >=, ===, !=, <>, !==et <=ou <et la >plupart devraient être utilisés que dans des expressions, telles que les ifexpressions. Si l'analyseur se plaint à leur sujet, cela signifie souvent une association incorrecte ou des ( )parens incompatibles autour d'eux.

  1. Groupement de Parens

    En particulier pour les ifinstructions avec plusieurs comparaisons, vous devez prendre soin de compter correctement les parenthèses d'ouverture et de fermeture :

                            
    if (($foo < 7) && $bar) > 5 || $baz < 9) { ... }
                          

    Ici, la ifcondition ici a déjà été résiliée par le)

    Une fois que vos comparaisons deviennent suffisamment complexes, il est souvent utile de les diviser en plusieurs ifconstructions imbriquées .

  2. isset () écrasé avec la comparaison

    Un nouveau venu commun est pitfal essaie de combiner isset()ou empty()avec des comparaisons:

                            
    if (empty($_POST["var"] == 1)) {

    Ou même:

                        
    if (isset($variable !== "value")) {

    Cela n'a pas de sens à PHP, parce que issetet emptysont des constructions de langage qui acceptent uniquement les noms de variables. Il n'est pas logique non plus de comparer le résultat, car la sortie est uniquement / déjà un booléen.

  3. Confondre >=supérieur ou égal avec l' =>opérateur de tableau

    Les deux opérateurs se ressemblent quelque peu, ils se mélangent donc parfois:

             
    if ($var => 5) { ... }

    Il suffit de se rappeler que cet opérateur de comparaison est appelé " supérieur ou égal " pour bien faire les choses.

    Voir aussi: Structure des instructions If en PHP

  4. Rien à comparer

    Vous ne pouvez pas non plus combiner deux comparaisons si elles appartiennent au même nom de variable:

                     
    if ($xyz > 5 and < 100)

    PHP ne peut pas déduire que vous vouliez à nouveau comparer la variable initiale. Les expressions sont généralement appariées en fonction de la priorité de l'opérateur , donc au moment où le <est vu, il ne resterait qu'un résultat booléen à partir de la variable d'origine.

    Voir aussi: inattendu T_IS_SMALLER_OR_EQUAL

  5. Chaînes de comparaison

    Vous ne pouvez pas comparer avec une variable avec une ligne d'opérateurs:

                      
     $reult = (5 < $x < 10);

    Cela doit être divisé en deux comparaisons, chacune contre $x.

    Il s'agit en fait davantage d'un cas d'expressions sur liste noire (en raison de l'associativité des opérateurs équivalents). Il est syntaxiquement valide dans quelques langages de style C, mais PHP ne l'interpréterait pas non plus comme une chaîne de comparaison attendue.

  6. Inattendu >
    inattendu<

    Les opérateurs supérieur >ou inférieur à <n'ont pas de T_XXXnom de tokenizer personnalisé . Et bien qu'ils puissent être égarés comme tous les autres, vous voyez plus souvent l'analyseur se plaindre d'eux pour des chaînes mal citées et du HTML écrasé:

                            
    print "<a href='z">Hello</a>";
                     ↑

    Cela revient à "<a href='z"comparer une chaîne >à une constante littérale Hello, puis à une autre <comparaison. Ou c'est du moins ce que PHP voit. L'erreur réelle de cause et de syntaxe était la "terminaison prématurée de la chaîne .

    Il n'est pas non plus possible d'imbriquer des balises de démarrage PHP:

    <?php echo <?php my_func(); ?>

Voir également:

mario
la source
11

T_IF
inattendu T_FOREACH
inattendu T_FOR
inattendu T_WHILE T_DO
inattendu T_ECHO
inattendu

Construit de contrôle tels que if, foreach, for, while, list, global, return, do, print, echone peuvent être utilisés comme des déclarations. Ils résident généralement seuls sur une ligne.

  1. Point-virgule; t'es où?

    Assez universellement, vous avez manqué un point-virgule dans la ligne précédente si l'analyseur se plaint d'une instruction de contrôle:

                 
    $x = myfunc()
    if (true) {

    Solution: regardez dans la ligne précédente; ajouter un point-virgule.

  2. Déclarations de classe

    Un autre emplacement où cela se produit est dans les déclarations de classe . Dans la section de classe, vous ne pouvez répertorier que les initialisations de propriété et les sections de méthode. Aucun code ne peut y résider.

    class xyz {
        if (true) {}
        foreach ($var) {}

    De telles erreurs de syntaxe se matérialisent généralement pour des erreurs d'imbrication {et }. En particulier lorsque les blocs de code de fonction se sont fermés trop tôt.

  3. Déclarations dans un contexte d'expression

    La plupart des constructions de langage ne peuvent être utilisées que comme des instructions . Ils ne sont pas destinés à être placés dans d'autres expressions:

                       
    $var = array(1, 2, foreach($else as $_), 5, 6);

    De même, vous ne pouvez pas utiliser une ifchaîne in, des expressions mathématiques ou ailleurs:

                   
    print "Oh, " . if (true) { "you!" } . " won't work";
    // Use a ternary condition here instead, when versed enough.

    Pour incorporer des ifconditions similaires à une expression en particulier, vous souhaitez souvent utiliser une ?:évaluation ternaire .

    De même pour for, while, global, echoet une moindre mesure list.

              
    echo 123, echo 567, "huh?";

    Considérant que print()est un langage intégré qui peut être utilisé dans un contexte d'expression. (Mais a rarement du sens.)

  4. Mots clés réservés comme identifiants

    Vous ne pouvez pas non plus utiliser doou ifet d'autres constructions de langage pour les fonctions définies par l'utilisateur ou les noms de classe. (Peut-être en PHP 7. Mais même alors, ce ne serait pas conseillé.)

mario
la source
7

Inattendu '?'

Si vous essayez d'utiliser l'opérateur de coalescence nulle ??dans une version de PHP antérieure à PHP 7, vous obtiendrez cette erreur.

<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP

'?' Inattendu, attend une variable

Une erreur similaire peut se produire pour les types nullables, comme dans:

function add(?int $sum): ?int {

Ce qui indique à nouveau une version PHP obsolète utilisée (soit la version CLI, soit la version php -vliée au serveur Web phpinfo();).

John Conde
la source
5

T_LNUMBER inattendu

Le jeton T_LNUMBERfait référence à un "long" / nombre.

  1. Noms de variables non valides

    En PHP et dans la plupart des autres langages de programmation, les variables ne peuvent pas commencer par un nombre. Le premier caractère doit être alphabétique ou un trait de soulignement.

    $1   // Bad
    $_1  // Good

    *

    • Il arrive assez souvent d'utiliser des preg_replace-placeholders "$1"dans le contexte PHP:

      #                         ↓            ⇓  ↓
      preg_replace("/#(\w+)/e",  strtopupper($1) )

      Où le rappel aurait dû être cité. (Maintenant, le /edrapeau regex est obsolète. Mais il est parfois encore mal utilisé dans les preg_replace_callbackfonctions.)

    • La même contrainte d'identifiant s'applique aux propriétés d'objet , btw.

             
      $json->0->value
    • Bien que le tokenizer / parser n'autorise pas un littéral $1comme nom de variable, on pourrait utiliser ${1}ou ${"1"}. Ce qui est une solution de contournement syntaxique pour les identificateurs non standard. (Il est préférable de le considérer comme une recherche de portée locale. Mais généralement: préférez les tableaux simples pour de tels cas!)

    • De manière amusante, mais fortement déconseillée, l'analyseur PHP autorise les identificateurs Unicode; tel $➊serait valable. (Contrairement à un littéral 1).

  2. Entrée de tableau parasite

    Un long inattendu peut également se produire pour les déclarations de tableau - en cas de ,virgule manquante :

    #            ↓ ↓
    $xy = array(1 2 3);

    Ou encore des appels de fonction et des déclarations, et d'autres constructions:

    • func(1, 2 3);
    • function xy($z 2);
    • for ($i=2 3<$z)

    Donc, généralement, il y en a un ;ou un ,manquant pour séparer les listes ou les expressions.

  3. HTML mal cité

    Et encore une fois, les chaînes mal citées sont une source fréquente de nombres errants:

    #                 ↓ ↓          
    echo "<td colspan="3">something bad</td>";

    De tels cas doivent être traités plus ou moins comme des erreurs T_STRING inattendues .

  4. Autres identifiants

    Ni les fonctions, ni les classes, ni les espaces de noms ne peuvent être nommés en commençant par un nombre:

             
    function 123shop() {

    À peu près la même chose que pour les noms de variables.

mario
la source
2

'=' Inattendu

Cela peut être dû à la présence de caractères non valides dans un nom de variable. Les noms de variables doivent suivre ces règles:

Les noms de variables suivent les mêmes règles que les autres étiquettes en PHP. Un nom de variable valide commence par une lettre ou un trait de soulignement, suivi d'un nombre quelconque de lettres, de chiffres ou de traits de soulignement. En tant qu'expression régulière, elle s'exprimerait ainsi: '[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] *'

John Conde
la source
Bon ajout John.
Funk Forty Niner
1

"Continuer" inattendu (T_CONTINUE)

continueest une instruction (comme pour ou si) et doit apparaître de façon autonome. Il ne peut pas être utilisé dans le cadre d'une expression. En partie parce que continue ne renvoie pas de valeur, mais dans une expression, chaque sous-expression doit entraîner une certaine valeur, de sorte que l'expression globale donne une valeur. Voilà la différence entre une déclaration et une expression.

Cela signifie continuequ'il ne peut pas être utilisé dans une instruction ternaire ou toute instruction nécessitant une valeur de retour.

"Pause" inattendue (T_BREAK)

Il en va break;de même bien sûr. Il n'est pas non plus utilisable dans un contexte d'expression, mais une déclaration stricte (au même niveau que foreachou un ifbloc).

«Retour» inattendu (T_RETURN)

Maintenant, cela pourrait être plus surprenant return, mais ce n'est qu'une déclaration au niveau du bloc . Il renvoie une valeur (ou NULL) à la portée / fonction supérieure, mais il n'évalue pas en tant qu'expression elle-même. → Autrement dit: il est inutile de fairereturn(return(false);;

mario
la source
1

Inattendu '.'

Cela peut se produire si vous essayez d'utiliser l' opérateur splat ( ...) dans une version non prise en charge de PHP.

... est devenu disponible en PHP 5.6 pour capturer un nombre variable d'arguments à une fonction:

function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES

En PHP 7.4, vous pouvez l'utiliser pour les expressions de tableau .

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
John Conde
la source
0

"Fin" inattendu (T_ENDWHILE)

La syntaxe utilise deux points - s'il n'y a pas de deux points l'erreur ci-dessus se produira.

<?php while($query->fetch()): ?>
 ....
<?php endwhile; ?>

L'alternative à cette syntaxe utilise des accolades:

<?php while($query->fetch()) { ?>
  ....
<?php } ?>

http://php.net/manual/en/control-structures. while.php

mplungjan
la source
0

Un message d'erreur qui commence Parse error: syntax error, unexpected ':'peut être provoqué en écrivant par erreur une référence statique de classe en Class::$Variabletant que Class:$Variable.

David Spector
la source