Obtenir le premier caractère d'une chaîne avec $str[0]
Je veux obtenir la première lettre d'une chaîne et j'ai remarqué que $str[0]
fonctionne très bien. Je ne suis tout simplement pas sûr que ce soit une "bonne pratique", car cette notation est généralement utilisée avec des tableaux. Cette fonctionnalité ne semble pas être très bien documentée, donc je me tourne vers vous pour me dire s'il est correct – à tous égards - d'utiliser cette notation?
Ou devrais-je m'en tenir au bon vieux substr($str, 0, 1)
?
Aussi, j'ai noté que les accolades ($str{0}
) fonctionne aussi bien. Qu'est-ce qui?
12 réponses
Oui. Les chaînes peuvent être considérées comme des tableaux de caractères, et la façon d'accéder à une position d'un tableau est d'utiliser l'opérateur []
. Habituellement, il n'y a aucun problème à utiliser $str[0]
(et je suis sûr que c'est beaucoup plus rapide que la méthode substr()
).
Il N'y a qu'une seule mise en garde avec les deux méthodes: elles obtiendront le premier octet, plutôt que le premier caractère. Ceci est important si vous utilisez des encodages multioctets (tels que UTF-8). Si vous voulez supporter cela, utilisez mb_substr()
. Sans doute, vous devriez toujours supposer une entrée multi-octets ces jours-ci, donc c'est la meilleure option , mais elle sera légèrement plus lente.
La {} syntaxe est obsolète depuis PHP 5.3.0. Les crochets sont recommandés.
Disons que vous voulez juste le premier caractère d'une partie de $_POST, appelons-le 'type'. Et que $_POST ['type'] est actuellement 'Control'. Si, dans ce cas si vous utilisez $_POST['type'][0]
, ou substr($_POST['type'], 0, 1)
vous obtenez C
retour.
Cependant, si le côté client devait modifier les données qu'il vous envoie, de type
à type[]
par exemple, puis envoyer 'Control' et 'Test' comme données pour ce tableau, $_POST['type'][0]
retournera maintenant Control
plutôt que C
alors que substr($_POST['type'], 0, 1)
échouera tout simplement.
Donc oui, il peut y avoir un problème avec l'utilisation de $str[0]
, mais qui dépend de la circonstance.
Mon seul doute serait de savoir à quel point cette technique serait applicable sur les chaînes multi-octets, mais si ce n'est pas une considération, alors je soupçonne que vous êtes couvert. (En cas de doute, mb_substr()
semble un choix évidemment sûr.)
Cependant, d'un point de vue général, je dois me demander à quelle fréquence vous devez accéder au 'n'ème caractère dans une chaîne pour que cela soit une considération clé.
Cela va varier en fonction des ressources, mais vous pouvez exécuter le script ci-dessous et voir par vous-même;)
<?php
$tests = 100000;
for ($i = 0; $i < $tests; $i++)
{
$string = md5(rand());
$position = rand(0, 31);
$start1 = microtime(true);
$char1 = $string[$position];
$end1 = microtime(true);
$time1[$i] = $end1 - $start1;
$start2 = microtime(true);
$char2 = substr($string, $position, 1);
$end2 = microtime(true);
$time2[$i] = $end2 - $start2;
$start3 = microtime(true);
$char3 = $string{$position};
$end3 = microtime(true);
$time3[$i] = $end3 - $start3;
}
$avg1 = array_sum($time1) / $tests;
echo 'the average float microtime using "array[]" is '. $avg1 . PHP_EOL;
$avg2 = array_sum($time2) / $tests;
echo 'the average float microtime using "substr()" is '. $avg2 . PHP_EOL;
$avg3 = array_sum($time3) / $tests;
echo 'the average float microtime using "array{}" is '. $avg3 . PHP_EOL;
?>
Quelques numéros de référence (sur une ancienne machine CoreDuo)
$ php 1.php
the average float microtime using "array[]" is 1.914701461792E-6
the average float microtime using "substr()" is 2.2536706924438E-6
the average float microtime using "array{}" is 1.821768283844E-6
$ php 1.php
the average float microtime using "array[]" is 1.7251944541931E-6
the average float microtime using "substr()" is 2.0931363105774E-6
the average float microtime using "array{}" is 1.7225742340088E-6
$ php 1.php
the average float microtime using "array[]" is 1.7293763160706E-6
the average float microtime using "substr()" is 2.1037721633911E-6
the average float microtime using "array{}" is 1.7249774932861E-6
Il semble que l'utilisation des opérateurs []
ou {}
est plus ou moins la même.
Parlant comme un simple mortel, je m'en tiendrais à $str[0]
. En ce qui me concerne, il est plus rapide de saisir la signification de $str[0]
en un coup d'œil que substr($str, 0, 1)
. Cela se résume probablement à une question de préférence.
En ce qui concerne la performance va, bien, profil Profil Profil. :) Ou vous pouvez regarder dans le code source PHP...
J'ai également utilisé cette notation auparavant, sans effets secondaires indésirables et sans malentendus. C'est logique - une chaîne est juste un tableau de caractères, après tout.
Dans le cas de chaînes multi-octets (unicode), l'utilisation de str[0]
peut causer des problèmes. mb_substr()
est une meilleure solution. Par exemple:
$first_char = mb_substr($title, 0, 1);
Quelques détails ici: obtenir le premier caractère de la chaîne UTF-8
Considérez ce qui suit:
<?php
var_dump($_POST);
// Post var is a string:
echo '1'; var_dump( strtoupper( $_POST['flag1'][0] ) === 'T' ); // boolean true
echo '2'; var_dump( strtoupper( substr( $_POST['flag1'],0,1 ) ) === 'T' ); // boolean true
// Post var is an array of strings
echo '5'; var_dump( strtoupper( $_POST['flag2'][0] ) === 'T' ); // boolean false
echo '6'; var_dump( strtoupper( substr( $_POST['flag2'],0,1 ) ) === 'T' ); // generates a PHP warning
?>
<hr />
<form method="POST">
<input type="text" name="name" value="bob" /><br />
<input type="text" name="flag1" value="true" /><br />
<select name="flag2[]" multiple>
<option value="true" selected>true</option>
<option value="false" selected>false</option>
<option value="0" selected>0</option>
</select><br />
<input type="submit" value="Submit" /><br />
</form>
L'intention est de détecter un drapeau booléen. Bien qu'il soit possible de confondre le problème en transformant le var en un type de tableau, l'utilisation de la notation array-indice produit un faux résultat sûr, alors que la fonction substr() produit une erreur. Étant donné le choix ici, j'irais avec la notation en indice.
Voici comment j'avais résolu le problème:
<?php
$string = 'Hello The World';
$stringExp = explode(' ', $string);
$shortCode = '';
for($i = 0; $i < count($stringExp); $i++):
$shortCode .= substr($stringExp[$i], 0, 1);
endfor;
echo $shortCode; // result : HTW
?>
Il est facile d'obtenir le premier caractère d'une chaîne. Traite la chaîne comme un tableau.
Exemple:
$first = $string{0};
$fifth = $string{5};
C'est ça!