So you want to get the last character of a string using "String access and modification by character"? Well negative indexes are not allowed so $str[-1] will return an empty string.
<?php
//Tested using: PHP 5.2.5
$str = 'This is a test.';
$last = $str[-1]; //string(0) ""
$realLast = $str[strlen($str)-1]; //string(1) "."
$substr = substr($str,-1); //string(1) "."
echo '<pre>';
var_dump($last);
var_dump($realLast);
var_dump($substr);
Strings
Ένα string είναι μια σειρά χαρακτήρων. Στην PHP, ένας χαρακτήρας είανι το ίδιο με ένα byte, δηλαδή, υπάρχουν ακριβώς 256 διαφορετικοί πιθανοί χαρακτήρες. Αυτό επίσης σημαίνει ότι η PHP δεν υποστηρίζει Unicode. Δείτε την utf8_encode() και την utf8_decode() σχετικά με υποστήριξη Unicode.
Note: Δεν υπάρχει πρόβλημα για ένα string να γίνει πολύ μεγάλο. Δεν υπάρχει πρακτικά κάποιο όριο για το μέγεθος των strings που να επιβάλλει η PHP, συνεπώς δεν υπάρχει λόγος να ανησυχείτε για μεγάλα strings.
Σύνταξη
Ένα λεκτικό string μπορεί να προσδιοριστεί με τρεις διαφορετικούς τρόπους.
Μονό εισαγωγικό (Single quoted)
Ο ευκολότερος τρόπος για να ορίσετε ένα απλό string είναι να το βάλετε μέσα σε μονά εισαγωγικά (δηλαδή στον χαρακτήρα ').
Για να ορίσετε ένα απλό εισαγωγικό, θα χρειαστεί να προσθέσετε ένα backslash (\), όπως και σε πολλές άλλες γλώσσες. Αν το backslash πρέπει να εμφανιστεί πριν από ένα απλό εισαγωγικό ή στο τέλος του string, θα χρειαστεί να το διπλασιάσετε. Σημειώστε ότι αν προσπαθήσετε να αποφύγετε (escape) οποιονδήποτε άλλο χαρακτήρα, το backslash θα τυπωθεί! Συνήθως δεν υπάρχει ανάγκη να θέλουμε να αποφύγουμε (escape) την εμφάνιση του ίδιου του backslash.
Note: Στην PHP 3, όταν συμβαίνει αυτό θα εμφανιστεί μια προειδοποίηση στο επίπεδο E_NOTICE .
Note: Σε αντίθεση με τις δύο άλλες συντάξεις, οι μεταβλητές και οι ακολουθίες από escape για ειδικούς χαρακτήρες δεν θα επεκταθεί όταν εμφανίζονται σε strings που ορίζονται από απλά εισαγωγικά.
<?php
echo 'this is a simple string';
echo 'You can also have embedded newlines in
strings this way as it is
okay to do';
// Outputs: Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\\*.*?';
// Outputs: You deleted C:\*.*?
echo 'You deleted C:\*.*?';
// Outputs: This will not expand: \n a newline
echo 'This will not expand: \n a newline';
// Outputs: Variables do not $expand $either
echo 'Variables do not $expand $either';
?>
Διπλά εισαγωγικά
Αν το string περικλείεται σε διπλά εισαγωγικά ("), η PHP καταλαβαίνει περισσότερες ακολουθίες από escape (escape sequences) για ειδικούς χαρακτήρες:
| sequence | meaning |
|---|---|
| \n | linefeed (LF or 0x0A (10) in ASCII) |
| \r | carriage return (CR or 0x0D (13) in ASCII) |
| \t | horizontal tab (HT or 0x09 (9) in ASCII) |
| \\ | backslash |
| \$ | dollar sign |
| \" | double-quote |
| \[0-7]{1,3} | η ακολουθία των χαρακτήρων που ταιριάζουν στην κανονική έκφραση είναι ένας χαρακτήρας στο οχταδικό σύστημα |
| \x[0-9A-Fa-f]{1,2} | η ακολουθία των χαρακτήρων που ταιριάζουν στην κανονική έκφραση είναι ένας χαρακτήρας στο δεκαεξαδικό σύστημα |
Επαναλαμβάνουμε ότι αν προσπαθήσετε να αποφύγετε (escape) οποιοδήποτε άλλο χαρακτήρα, το backslash θα τυπωθεί!
Αλλά το πιο σημαντικό χαρακτηριστικό των strings που ορίζονται σε διπλά εισαγωγικά είναι το γεγονός ότι τα ονόματα των μεταβλητών θα επεκταθούν. Δείτε το string parsing για λεπτομέρειες.
Heredoc
Ένας άλλος τρόπος για να ορίσουμε strings είναι χρησιμοποιώντας τη σύνταξη heredoc ("<<<"). Θα πρέπει να προσθέσουμε έναν identifier μετά τα <<<, στη συνέχεια το string, και μετά τον ίδιο identifier για να κλείσουμε την αναφορά.
Ο identifier κλεισίματος πρέπει να αρχίζει στην πρώτη στήλη της γραμμής. Επίσης, ο identifier που χρησιμοποιείται πρέπει να ακολουθεί τους ίδιους κανόνες ονοματολογίας όπως και οποιοδήποτε άλλο label στην PHP: πρέπει να περιέχει μόνο αλφαριθμητικούς χαρακτήρες και underscores, και πρέπει να αρχίζει με ένα μη αριθμητικό χαρακτήρα ή underscore.
Είναι πολύ σημαντικό να σημειώσουμε ότι η γραμμή με τον identifier κλεισίματος δεν περιέχει άλλους χαρακτήρες, εκτός ίσως από ένα ελληνικό ερωτηματικό (;). Αυτό σημαίνει ιδιαίτερα ότι ο identifier μπορεί να μην βρίσκεται σε εσοχή (quote), και μπορεί να μην υπάρχουν spaces ή tabs μετά ή πριν το ελληνικό ερωτηματικό. Είναι επίσης σημαντικό να συνειδητοποιήσετε ότι ο πρώτος χαρακτήρας πριν τον identifier κλεισίματος πρέπει να είναι μια καινούρια γραμμή (newline) όπως αυτή ορίζεται από το λειτουργικό σας σύστημα. Αυτό είναι το \r στο Macintosh για παράδειγμα.
Αν αυτός ο κανόνας δεν τηρείται και ο identifier κλεισίματος δεν είναι "ξεκάθαρος" τότε δεν θεωρείται ότι είναι identifier κλεισίματος και η PHP θα συνεχίσει να ψάχνει για έναν τέτοιο. Αν σ'αυτή την περίπτωση ένας κατάλληλος identifier κλεισίματος δεν βρεθεί τότε ένα parse error θα εμφανιστεί με τον αριθμό της γραμμής που τελειώνει το script.
Το Heredoc text συμπεριφέρεται ακριβώς όπως το double-quoted string, χωρίς όμως τα double-quotes. Αυτό σημαίνει πως δεν χρειάζεται να προσπαθείτε να κάνετε escape quotes στα έγγραφα σας εδώ, αλλά μπορείτε να χρησιμοποιείτε τους κώδικες για escape που αναφέρθηκαν παραπάνω. Οι μεταβλητές επεκτείνονται, αλλά η ίδια προσοχή πρέπει να δίνεται όταν εκφράζουμε σύνθετες μεταβλητές μέσα σε ένα τέτοιο έγγραφο όπως και με τα strings.
Example#1 Παράδειγμα Heredoc string quoting
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
/* More complex example, with variables. */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MyName';
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>
Note: Η υποστήριξη Heredoc προστέθηκε στην PHP 4.
Μεταγλώττιση Μεταβλητών
Όταν ένα string ορίζεται σε double quotes ή με heredoc, οι μεταβλητές μεταγλωττίζονται μέσα σ'αυτό.
Υπάρχουν δυο τρόποι σύνταξης, ο απλός και ο σύνθετος . Ο απλός τρόπος σύνταξης είναι ο πιο κοινός και βολικός, παρέχει έναν τρόπο για μεταγλώττιση μεταβλητής, μιας τιμής ενός array, ή μια ιδιότητας αντικειμένου.
Ο σύνθετος τρόπος σύνταξης εισήχθη στην PHP 4, και μπορεί να αναγνωριστεί από τα curly braces (άγκιστρα) που περιβάλουν την έκφραση.
Απλή σύνταξη
Αν το σύμβολο του δολαρίου ($) εμφανιστεί, ο parser (μεταγλωττιστής) θα πάρει όσο πιο πολλά tokens μπορεί για να σχηματίσει ένα έγκυρο όνομα μεταβλητής. Βάλτε το όνομα της μεταβλητής σε curly braces αν θέλετε να καθορίσετε ρητά το τέλος του ονόματος.
<?php
$beer = 'Heineken';
echo "$beer's taste is great"; // works, "'" is an invalid character for varnames
echo "He drank some $beers"; // won't work, 's' is a valid character for varnames
echo "He drank some ${beer}s"; // works
echo "He drank some {$beer}s"; // works
?>
Ομοιώς, μπορείτε να έχετε ένα array index ή μία ιδιότητα αντικειμένου για μεταγλώττιση. Στα ευρετήρια πινάκων, η αγκύλη κλεισίματος (]) ορίζει το τέλος του ευρετηρίου. Για τις ιδιότητες αντικειμένων οι ίδιοι κανόνες εφαρμόζονται όπως και στις απλές μεταβλητές, ενώ με τις ιδιότητες αντικειμένων δεν υπάρχει τέτοιο trick όπως αυτό με τις μεταβλητές.
<?php
// These examples are specific to using arrays inside of strings.
// When outside of a string, always quote your array string keys
// and do not use {braces} when outside of strings either.
// Let's show all errors
error_reporting(E_ALL);
$fruits = array('strawberry' => 'red', 'banana' => 'yellow');
// Works but note that this works differently outside string-quotes
echo "A banana is $fruits[banana].";
// Works
echo "A banana is {$fruits['banana']}.";
// Works but PHP looks for a constant named banana first
// as described below.
echo "A banana is {$fruits[banana]}.";
// Won't work, use braces. This results in a parse error.
echo "A banana is $fruits['banana'].";
// Works
echo "A banana is " . $fruits['banana'] . ".";
// Works
echo "This square is $square->width meters broad.";
// Won't work. For a solution, see the complex syntax.
echo "This square is $square->width00 centimeters broad.";
?>
Για κάτι πιο πολύπλοκο, θα πρέπει να χρησιμοποιείτε τη σύνθετη σύνταξη.
Σύνθετη (curly) σύνταξη
Η σύνταξη αυτή δεν καλείται σύνθετη επειδή είναι η ίδια σύνθετη, αλλά επειδή μπορείτε να συμπεριλάβετε σύνθετες εκφράσεις με αυτόν τον τρόπο.
Στην πραγματικότητα, μπορείτε να συμπεριλάβετε οποιαδήποτε τιμή υπάρχει στο namespace των strings με αυτή τη σύνταξη. Απλά γράφετε την έκφραση με τον ίδιο τρόπο που θα τη γράφατε έξω από το string, και στη συνέχεια να την συμπεριλάβετε στα { και }. Αφού δεν μπορείτε να κάνετε escape στο '{', αυτή η σύνταξη θα αναγνωρίζεται μόνο όταν το $ ακολουθεί αμέσως το {. (Χρησιμοποιείστε το "{\$" ή το "\{$" για να πάρετε το λεκτικό "{$"). Μερικά παραδείγματα για να το κάνουν πιο ξεκάθαρο:
<?php
// Let's show all errors
error_reporting(E_ALL);
$great = 'fantastic';
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
echo "This is ${great}";
// Works
echo "This square is {$square->width}00 centimeters broad.";
// Works
echo "This works: {$arr[4][3]}";
// This is wrong for the same reason as $foo[bar] is wrong
// outside a string. In otherwords, it will still work but
// because PHP first looks for a constant named foo, it will
// throw an error of level E_NOTICE (undefined constant).
echo "This is wrong: {$arr[foo][3]}";
// Works. When using multi-dimensional arrays, always use
// braces around arrays when inside of strings
echo "This works: {$arr['foo'][3]}";
// Works.
echo "This works: " . $arr['foo'][3];
echo "You can even write {$obj->values[3]->name}";
echo "This is the value of the var named $name: {${$name}}";
?>
String που προσπελαύνονται από χαρακτήρες
Οι χαρακτήρες μέσα σε strings μπορούν να προσπελαστούν ορίζοντας το zero-based offset του επιθυμητού χαρακτήρα μετά το string σε curly braces.
Note: Για προς τα πίσω συμβατότητα, μπορείτε ακόμη να χρησιμοποιείτε array-braces για τον ίδιο σκοπό. Πάντως, αυτή η σύνταξη δεν συνίσταται στην PHP 4.
Example#2 Μερικά παραδείγματα από strings
<?php
// Get the first character of a string
$str = 'This is a test.';
$first = $str{0};
// Get the third character of a string
$third = $str{2};
// Get the last character of a string.
$str = 'This is still a test.';
$last = $str{strlen($str)-1};
?>
Χρήσιμες συναρτήσεις και τελεστές
Τα strings μπορούν να συννενωθούν χρησιμοποιώντας τον τελεστή '.' (τελεία). Σημειώστε ότι ο '+' (συν) τελεστής δε θα δουλέψει σ'αυτή την περίπτωση. Παρακαλώ δείτε το Τελεστές για Strings για περισσότερες πληροφορίες.
Υπάρχουν πολλές χρήσιμες συναρτήσεις για αλλαγές στα strings.
Δείτε το τμήμα για συναρτήσεις των strings για γενικές συναρτήσεις, τις συναρτήσεις κανονικών εκφράσεων για προχωρημένη αναζήτηση&αντικατάσταση (σε δυο εκδόσεις: Perl και POSIX extended).
Υπάρχουν επίσης συναρτήσεις για URL-strings, και συναρτήσεις για κρυπτογράφηση/αποκρυπτογράφηση strings (mcrypt και mhash).
Τέλος, αν ακόμη δεν βρήκατε αυτό που ψάχνατε, δείτε επίσης τις συναρτήσεις για τύπους χαρακτήρων.
Μετατρέποντας σε string
Μπορείτε να μετατρέψετε μια τιμή σε string χρησιμοποιώντας την (string) cast (μεατροπή), ή τη συνάρτηση strval(). Η μετρατοπή σε String γίνεται αυτόματα για σας στην εμβέλεια της έκφρασης όταν απαιτείται ένα string. Αυτό συμβαίνει όταν χρησιμοποιείτε τις echo() ή print() συναρτήσεις, ή όταν συγκρίνετε μια μεταβλητή τιμή με ένα string. Διαβάστε στο manual τα τμήματα σχετικά με Τύπους και Type Juggling για να καταλάβετε καλύτερα. Δείτε επίσης settype().
Μια boolean TRUE τιμή μετατρέπεται στο string "1", ενώ η FALSE τιμή αναπαρίσταται από το "" (κενό string). Μ'αυτόν τον τρόπο μπορείτε να μετατρέψετε τις τιμές από boolean σε string και αντιστρόφως.
Ένας integer ή ένας αριθμός κινητής υποδιαστολής (float) όταν μετατρέπεται string αναπαρίσταται από τον αριθμό με τα ψηφία του (συμπεριλαμβάνεται το μέρος του εκθέτη για τους αριθμούς κινητής υποδιαστολής).
Οι Arrays μετατρέπονται πάντα στο string "Array", έτσι δεν μπορείτε να εμφανίσετε το περιεχόμενο ενός array με την echo() ή την print() για να δείτε τι υπάρχει μέσα σ'αυτούς. Για να δείτε ένα στοιχείο, θα κάνετε κάτι όπως echo $arr['foo']. Δείτε παρακάτω για tips σχετικά με την εμφάνιση ολόκληρου του περιεχομένου.
Τα Objects μετατρέπονται πάντα στο string "Object". Αν θέλετε να εκτυπώσετε τη τιμή ενός μέλους της μεταβλητής ενός object για λόγους debugging, διαβάστε τις παρακάτω παραγράφους. Αν θέλετε να βρείτε το όνομα της κλάσης της οποίας ένα object είναι στιγμιότυπο (instance), χρησιμοποιείστε την get_class().
Τα Resources πάντα μετατρέπονται σε strings με τη δομή "Resource id #1" όπου το 1 είναι ο μοναδικός αριθμός του resource που ανατίθεται από την PHP κατά τη διάρκεια της εκτέλεσης. Αν θέλετε να πάρετε τον τύπο του resource, χρησιμοποιείστε την get_resource_type().
Το NULL μετατρέπεται πάντα σε κενό string.
Όπως μπορείτε να δείτε παραπάνω, η εκτύπωση των arrays, των objects ή των resources δεν σας παρέχει χρήσιμες πληροφορίες σχετικά τις ίδιες τις τιμές. Δείτε τις συναρτήσεις print_r() και var_dump() για καλύτερους τρόπους εμφάνισης των τιμών για το debugging.
Μπορείτε επίσης να μετατρέψετε τις τιμές της PHP σε strings και να τις αποθηκεύσετε μόνιμα. Αυτή η μέθοδος ονομάζεται serialization, και μπορεί να γίνει με τη συνάρτηση serialize(). Μπορείτε επίσης να κάνετε serialize τις PHP values σε XML δομές, αν έχετε προσθέσει υποστήριξη για WDDX κατά τη διάρκεια του setup της PHP.
Μετατροπή των Strings σε αριθμούς
Όταν ένα string υπολογίζεται σαν αριθμητική τιμή, η τιμή που προκύπτει και ο τύπος της ορίζονται ως ακολούθως.
Το string θα υπολογιστεί ως float αν περιέχει οποιοδήποτε από τους χαρακτήρες '.', 'e', or 'E'. Διαφορετικά, θα υπολογιστεί ως ακέραιος.
Η τιμή δίνεται από το αρχικό μέρος του string. Αν το string αρχίζει με ένα έγκυρο αριθμητικό δεδομένο, αυτή θα είναι και η τιμή που θα χρησιμοποιηθεί. Διαφορετικά, η τιμή θα είναι 0 (μηδέν). Τα έγκυρα αριθμητικά δεδομένα είναι ένα προαιρετικό σύμβολο, ακολουθούμενο από ένα ή περισσότερα ψηφία (προαιρετικά περιλαμβάνουν ένα δεκαδικό σημείο), ακολουθούμενο από ένα προαιρετικό εκθετικό. Το εκθετικό είναι το 'e' ή το 'E' ακολουθούμενο από ένα ή περισσότερα ψηφία.
<?php
$foo = 1 + "10.5"; // $foo is float (11.5)
$foo = 1 + "-1.3e3"; // $foo is float (-1299)
$foo = 1 + "bob-1.3e3"; // $foo is integer (1)
$foo = 1 + "bob3"; // $foo is integer (1)
$foo = 1 + "10 Small Pigs"; // $foo is integer (11)
$foo = 4 + "10.2 Little Piggies"; // $foo is float (14.2)
$foo = "10.0 pigs " + 1; // $foo is float (11)
$foo = "10.0 pigs " + 1.0; // $foo is float (11)
?>
Για περισσότερες πληροφορίες σχετικά με αυτή τη μετατροπή, δείτε το manual του Unix στη σελίδα για strtod(3).
Αν θέλετε να ελένξετε κάποιο από τα παραδείγματα σ'αυτό το τμήμα, μπορείτε να κάνετε cut και paste στα παραδείγματα και να εισάγετε την ακόλουθη γραμμή για να δείτε μόνοι σας τι συμβαίνει:
<?php
echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";
?>
Μην περιμένετε να πάρετε τον κώδικα από έναν χαρακτήρα απλά μετατρέποντας τον σε ακέραιο (όπως θα κάνατε στη C για παράδειγμα). Χρησιμοποιήστε τις συναρτήσεις ord() και chr() για μετατροπές ανάμεσα σε charcodes και characters.
Strings
01-Sep-2008 03:05
06-Jun-2008 12:40
It's also valuable to note the following:
<?php
${date("M")} = "Worked";
echo ${date("M")};
?>
This is perfectly legal, anything inside the braces is executed first, the return value then becomes the variable name. Echoing the same variable variable using the function that created it results in the same return and therefore the same variable name is used in the echo statement. Have fun ;).
30-Apr-2008 12:46
<?php
$F = "F";
function F($s) { return $s; }
$filename = '<some code>';
echo "{$F(htmlspecialchars($filename))}";
?>
31-Mar-2008 07:21
This example of the heredoc has wrong output:
Code: This should print a capital 'A': \x41
Output should be: This should print a capital 'A': A
The example of the nowdoc has wrong code:
Code: This should not print a capital 'A': x41
That should be: This should not print a capital 'A': \x41
24-Mar-2008 07:58
For anyone who reads Evan K, please note that:
// a string to test, and show the before and after
$before = 'Quantity:\t500\nPrice:\t$5.25 each';
$after = expand_escape($before);
var_dump($before, $after);
Is identical to (note all I added was a backslash before $):
$before = "Quantity:\t500\nPrice:\t\$5.25 each";
var_dump($before);
So its definitely better to escape a dollar instead of all the overhead of his regex and evals and such, although clever completely unnecessary.
-Chris
28-Feb-2008 01:03
I encountered the odd situation of having a string containing unexpanded escape sequences that I wanted to expand, but also contained dollar signs that would be interpolated as variables. "$5.25\n", for example, where I want to convert \n to a newline, but don't want attempted interpolation of $5.
Some muddling through docs and many obscenties later, I produced the following, which expands escape sequences in an existing string with NO interpolation.
<?php
// where we do all our magic
function expand_escape($string) {
return preg_replace_callback(
'/\\\([nrtvf]|[0-7]{1,3}|[0-9A-Fa-f]{1,2})?/',
create_function(
'$matches',
'return ($matches[0] == "\\\\") ? "" : eval( sprintf(\'return "%s";\', $matches[0]) );'
),
$string
);
}
// a string to test, and show the before and after
$before = 'Quantity:\t500\nPrice:\t$5.25 each';
$after = expand_escape($before);
var_dump($before, $after);
/* Outputs:
string(34) "Quantity:\t500\nPrice:\t$5.25 each"
string(31) "Quantity: 500
Price: $5.25 each"
*/
?>
06-Feb-2008 10:31
I think there's not that much to string comparison as claiming date recognition:
It's simply comparing ordinal values of the characters from the {0} to the {strlen-1} one.
In this case
<?php
$a = '2007-11-06 15:17:48';
$b = '2007-11-05 15:17:48';
var_dump($a > $b);
?>
mArIo@luigi ~ $: php test.php
bool(true)
here all characters match till it reaches position 9 (the "day")
there, 6 has a bigger ord()inal value than 5
<?php
$a = 'January 25th, 2008 00:23:38';
$b = 'Janury 24th, 2008 00:23:37'; // ($a > $b) === false
?>
Here when we reach 'r' in "Janury" we see that "a" is "less" than "r" so the example would evaluate as ($a < $b) === true
Here:
<?php
$a = 'February 1st, 2008 00:23:38';
$b = 'January 25th, 2008 00:23:38';
?>
as expected the letter "F" comes before "J" as an ordinal character, so $a is less than $b
Even here:
<?php
var_dump('Z' > 'M'); //bool(true)
?>
it gets confirmed that the string comparison operators >, <, =>, =<, == just do a ordinal character comparison starting from position {0} to the first difference or the end of the string.
28-Jan-2008 08:25
@qriz at example dot com
Numerical comparisons, such as <, > are simply _NOT_ valid on strings. Thus, before a comparison can be made by a numerical comparison operator, the operands must be _casted_ to a numerical type (either float or int). What I was attempting to say in my previous post is that >, < are date-aware; the tests I included were examples, and not intended to represent the full scope of my comparison.
"Works correctly since there is a comparing between strings. The comparisson is done on the last number/letter (since thats the only thing that is difference in the string) and that is in this case: the 9 and 8."
What you say here is mere assumption; a few quick tests show that this is indeed not the case. If PHP indeed compares only the last character in the string, then the following assertion should be false:
test.php:
<?php
$a = '2007-11-06 15:17:48';
$b = '2007-11-05 15:17:48';
var_dump($a > $b);
?>
mArIo@luigi ~ $: php test.php
bool(true)
Further, consider the following choices for $a and $b, which, as expected, demonstrate that the <, > operators can indeed understand date formats:
<?php
$a = 'January 25th, 2008 00:23:37';
$b = 'January 24th, 2008 00:23:38'; // ($a > $b) === true, but 8
?>
If you remain unconvinced, consider what happens if I spell January incorrectly:
<?php
$a = 'January 25th, 2008 00:23:38';
$b = 'Janury 24th, 2008 00:23:37'; // ($a > $b) === false
?>
Looks like it can understand ISO 8601 date formats? (for more information, see http://en.wikipedia.org/wiki/ISO_8601)
Further investigation yields that this doesn't even work as it should:
<?php
$a = 'February 1st, 2008 00:23:38';
$b = 'January 25th, 2008 00:23:38';
var_dump($a > $b); //bool(false)
var_dump(strtotime($a)); //int(1201843418)
var_dump(strtotime($b)); //int(1201238618)
var_dump(strtotime($a) - strtotime($b)); //int(604800)
?>
Keeping $b constant and varying the month in $a shows that this comparison correctly interprets the date with the following months: January,March,May,June,July,September,October,November. Interestingly enough, these are all the months having the property that ord($a[0]) >= ord($b[0]).
<?php
var_dump('Z' > 'M'); //bool(true)
?>
Conclusion:
The <,> comparison operators definitely have functionality that is undocumented, including date awareness; however, this functionality may not always work as expected and should not be trusted for portability.
22-Jan-2008 06:38
this is the sql string that use the variable and and \' and function.It generate the correct result.
$sql1=<<<EOT
INSERT INTO hp_visitHistory ( col1,col2,col3)
VALUES ( NOW(), '{$col2}', '{$_SERVER['REQUEST_URI']}')
EOT;
echo $sql1;
13-Nov-2007 09:54
<?php
$a = '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';
$bool = $a > $b;
var_dump($bool); //bool(true)
?>
works correctly since there is a comparing between strings. The comparisson is done on the last number/letter (since thats the only thing that is difference in the string) and that is in this case: the 9 and 8.
8 > 9 = true
if you want to compare the string as pure numbers then you must type cast it to numbers or type juggle it:
<?php
$a = '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';
$bool1 = ($a + 0) > ($b + 0); // 2007 > 2007
$bool2 = (int) $a > (int) $b; // 2007 > 2007
$bool3 = intval($a) > intval($b); // 2007 > 2007
var_dump($bool1,$bool2,$bool3); //bool(false)
?>
05-Nov-2007 04:48
I have come across this several times, and as far as I can tell, the < and > operators have undocumented functionality when it comes to comparing strings. Consider the following script:
<?php
$a = '2007-11-05 15:17:49';
$b = '2007-11-05 15:17:48';
$bool = $a > $b;
var_dump($bool); //bool(true)
/**
* The manual tells us that $a and $b should be
* truncated at -, thus giving a floating-point value of 2007.
* But (2007 > 2007) === false...
*/
$a = (float)$a;
$b = (float)$b;
var_dump($a); //float(2007);
var_dump($b); //float(2007);
/**
* And the manual is right. So why does it correctly
* compare the dates (which should be treated
* as normal strings? Clearly some hidden functionality...
*/
26-Sep-2007 12:35
If you want to use a variable in an array index within a double quoted string you have to realize that when you put the curly braces around the array, everything inside the curly braces gets evaluated as if it were outside a string. Here are some examples:
<?php
$i = 0;
$myArray[Person0] = Bob;
$myArray[Person1] = George;
// prints Bob (the ++ is used to emphasize that the expression inside the {} is really being evaluated.)
echo "{$myArray['Person'.$i++]}<br>";
// these print George
echo "{$myArray['Person'.$i]}<br>";
echo "{$myArray["Person{$i}"]}<br>";
// These don't work
echo "{$myArray['Person$i']}<br>";
echo "{$myArray['Person'$i]}<br>";
// These both throw fatal errors
// echo "$myArray[Person$i]<br>";
//echo "$myArray[Person{$i}]<br>";
?>
07-Jul-2007 12:51
Heredocs can be used for more than just echoing or setting variables - use them whenever you want to include a string.
function header() {
return <<<EOT
<html>
<head>
<title>This is my heredoc</title>
</head>
<body>
EOT;
Also, note the strict syntax:
- No semicolon after initial EOT (think of the heredoc as a literal string arg - you wouldn't want a semicolon in front of it, would you?)
- BUT need semicolon after final EOT (the command is finished here)
- Final EOT is on the left margin - don't indent it!
03-Jul-2007 02:32
Function calls within double-quote variable interpolation work in PHP 5, but not quite as you'd expect. Basically the function has to be a variable function. I.e. a variable that holds the name of a function. So if you've got a function named 'x' that you want to call, you'll have to assign the function name to a variable. It's easiest to just assign it to a variable with the same name:
function x () { return 4; }
$x = 'x';
echo "x = {$x()}";
I'm not sure what the point of that is though, since it would be easier to do it this way:
function x () { return 4; }
$x = x();
echo "x = $x";
31-May-2007 08:31
Unlike bash, we can't do
echo "\a" #beep!
Of course, that would be rather meaningless for PHP/web, but it's useful for PHP-CLI. The solution is simple: echo "\x07"
25-Apr-2007 05:06
easy transparent solution for using constants in the heredoc format:
DEFINE('TEST','TEST STRING');
$const = get_defined_constants();
echo <<<END
{$const['TEST']}
END;
Result:
TEST STRING
24-Apr-2007 10:14
error control operator (@) with heredoc syntax:
the error control operator is pretty handy for supressing minimal errors or omissions. For example an email form that request some basic non mandatory information to your users. Some may complete the form, other may not. Lets say you don't want to tweak PHP for error levels and you just wish to create some basic template that will be emailed to the admin with the user information submitted. You manage to collect the user input in an array called $form:
<?php
// creating your mailer
$mailer = new SomeMailerLib();
$mailer->from = ' System <mail@yourwebsite.com>';
$mailer->to = 'admin@yourwebsite.com';
$mailer->subject = 'New user request';
// you put the error control operator before the heredoc operator to suppress notices and warnings about unset indices like this
$mailer->body = @<<<FORM
Firstname = {$form['firstname']}
Lastname = {$form['lastname']}
Email = {$form['email']}
Telephone = {$form['telephone']}
Address = {$form['address']}
FORM;
?>
01-Apr-2007 08:44
A simple benchmark to check differents about :
- simple and double quote concatenation and
- double quote and heredoc replacement
<?php
function test_simple_quote_concat()
{
$b = 'string';
$a = ' string'.$b.' string'.$b.' srting'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
$a .= ' string'.$b.' string'.$b.' string'.$b;
}
function test_double_quote_concat()
{
$b = "string";
$a = " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
$a .= " string".$b." string".$b." string".$b;
}
function test_double_quote_replace()
{
$b = "string";
$a = " string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b
string$b string$b string$b";
}
function test_eot_replace()
{
$b = <<<EOT
string
EOT;
$a = <<<EOT
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
string{$b} string{$b} string{$b}
EOT;
}
$iter = 2000;
for( $i=0; $i<$iter; $i++ )
test_simple_quote_concat();
for( $i=0; $i<$iter; $i++ )
test_double_quote_concat();
for( $i=0; $i<$iter; $i++ )
test_double_quote_replace();
for( $i=0; $i<$iter; $i++ )
test_eot_replace();
?>
I've use xdebug profiler to obtain the followed results:
test_simple_quote_concat : 173ms
test_double_quote_concat : 161ms
test_double_quote_replace : 147ms
test_eot_replace : 130ms
27-Feb-2007 12:16
As of (at least) PHP 5.2, you can no longer convert an object to a string unless it has a __toString method. Converting an object without this method now gives the error:
PHP Catchable fatal error: Object of class <classname> could not be converted to string in <file> on line <line>
Try this code to get the same results as before:
<?php
if (!is_object($value) || method_exists($value, '__toString')) {
$string = (string)$value;
} else {
$string = 'Object';
}
?>
21-Feb-2007 10:20
It may be obvious to some, but it's convenient to note that variables _will_ be expanded inside of single quotes if these occur inside of a double-quoted string. This can be handy in constructing exec calls with complex data to be passed to other programs. e.g.:
$foo = "green";
echo "the grass is $foo";
the grass is green
echo 'the grass is $foo';
the grass is $foo
echo "the grass is '$foo'";
the grass is 'green'
28-Mar-2006 12:58
You may use heredoc syntax to comment out large blocks of code, as follows:
<?php
<<<_EOC
// end-of-line comment will be masked... so will regular PHP:
echo ($test == 'foo' ? 'bar' : 'baz');
/* c-style comment will be masked, as will other heredocs (not using the same marker) */
echo <<<EOHTML
This is text you'll never see!
EOHTML;
function defintion($params) {
echo 'foo';
}
class definition extends nothing {
function definition($param) {
echo 'do nothing';
}
}
how about syntax errors?; = gone, I bet.
_EOC;
?>
Useful for debugging when C-style just won't do. Also useful if you wish to embed Perl-like Plain Old Documentation; extraction between POD markers is left as an exercise for the reader.
Note there is a performance penalty for this method, as PHP must still parse and variable substitute the string.
30-Nov-2005 08:57
Use caution when you need white space at the end of a heredoc. Not only is the mandatory final newline before the terminating symbol stripped, but an immediately preceding newline or space character is also stripped.
For example, in the following, the final space character (indicated by \s -- that is, the "\s" is not literally in the text, but is only used to indicate the space character) is stripped:
$string = <<<EOT
this is a string with a terminating space\s
EOT;
In the following, there will only be a single newline at the end of the string, even though two are shown in the text:
$string = <<<EOT
this is a string that must be
followed by a single newline
EOT;
01-Nov-2005 08:05
Just some quick observations on variable interpolation:
Because PHP looks for {? to start a complex variable expression in a double-quoted string, you can call object methods, but not class methods or unbound functions.
This works:
<?php
class a {
function b() {
return "World";
}
}
$c = new a;
echo "Hello {$c->b()}.\n"
?>
While this does not:
<?php
function b() {
return "World";
}
echo "Hello {b()}\n";
?>
Also, it appears that you can almost without limitation perform other processing within the argument list, but not outside it. For example:
<?
$true = true;
define("HW", "Hello World");
echo "{$true && HW}";
?>
gives: Parse error: parse error, unexpected T_BOOLEAN_AND, expecting '}' in - on line 3
There may still be some way to kludge the syntax to allow constants and unbound function calls inside a double-quoted string, but it isn't readily apparent to me at the moment, and I'm not sure I'd prefer the workaround over breaking out of the string at this point.
27-Oct-2004 12:01
You can use the complex syntax to put the value of both object properties AND object methods inside a string. For example...
<?php
class Test {
public $one = 1;
public function two() {
return 2;
}
}
$test = new Test();
echo "foo {$test->one} bar {$test->two()}";
?>
Will output "foo 1 bar 2".
However, you cannot do this for all values in your namespace. Class constants and static properties/methods will not work because the complex syntax looks for the '$'.
<?php
class Test {
const ONE = 1;
}
echo "foo {Test::ONE} bar";
?>
This will output "foo {Test::one} bar". Constants and static properties require you to break up the string.
06-Aug-2004 12:03
A note on the heredoc stuff.
If you're editing with VI/VIM and possible other syntax highlighting editors, then using certain words is the way forward. if you use <<<HTML for example, then the text will be hightlighted for HTML!!
I just found this out and used sed to alter all EOF to HTML.
JAVASCRIPT also works, and possibly others. The only thing about <<<JAVASCRIPT is that you can't add the <script> tags.., so use HTML instead, which will correctly highlight all JavaScript too..
You can also use EOHTML, EOSQL, and EOJAVASCRIPT.
28-Apr-2004 07:49
watch out when comparing strings that are numbers. this example:
<?php
$x1 = '111111111111111111';
$x2 = '111111111111111112';
echo ($x1 == $x2) ? "true\n" : "false\n";
?>
will output "true", although the strings are different. With large integer-strings, it seems that PHP compares only the integer values, not the strings. Even strval() will not work here.
To be on the safe side, use:
$x1 === $x2
11-Apr-2004 03:53
Here is a possible gotcha related to oddness involved with accessing strings by character past the end of the string:
$string = 'a';
var_dump($string[2]); // string(0) ""
var_dump($string[7]); // string(0) ""
$string[7] === ''; // TRUE
It appears that anything past the end of the string gives an empty string.. However, when E_NOTICE is on, the above examples will throw the message:
Notice: Uninitialized string offset: N in FILE on line LINE
This message cannot be specifically masked with @$string[7], as is possible when $string itself is unset.
isset($string[7]); // FALSE
$string[7] === NULL; // FALSE
Even though it seems like a not-NULL value of type string, it is still considered unset.
19-Jan-2004 03:41
By the way, the example with the "\n" sequence will insert a new line in the html code, while the output will be decided by the HTML syntax. That's why, if you use
<?
echo "Hello \n World";
?>
the browser will receive the HTML code on 2 lines
but his output on the page will be shown on one line only.
To diplay on 2 lines simply use:
<?
echo "Hello <br>World";
?>
like in HTML.
11-Apr-2003 05:37
Note that in PHP versions 4.3.0 and 4.3.1, the following provides a bogus E_NOTICE (this is a known bug):
echo "$somearray['bar']";
This is accessing an array inside a string using a quoted key and no {braces}. Reading the documention shows all the correct ways to do this but the above will output nothing on most systems (most have E_NOTICE off) so users may be confused. In PHP 4.3.2, the above will again yield a parse error.
Regarding "String access by character":
Apparently if you edit a specific character in a string, causing the string to be non-continuous, blank spaces will be added in the empty spots.
echo '<pre>';
$str = '0123';
echo "$str\n";
$str[4] = '4';
echo "$str\n";
$str[6] = '6';
echo "$str\n";
This will output:
0123
01234
01234 6
Notice the blank space where 5 should be.
03-Nov-2002 05:41
Even if the correct way to handle variables is determined from the context, some things just doesn't work without doing some preparation.
I spent several hours figuring out why I couldn't index a character out of a string after doing some math with it just before. The reason was that PHP thought the string was an integer!
$reference = $base + $userid;
.. looping commands ..
$chartohandle = $reference{$last_char - $i};
Above doesn't work. Reason: last operation with $reference is to store a product of an addition -> integer variable. $reference .=""; (string catenation) had to be added before I got it to work:
$reference = $base + $userid;
$reference .= "";
.. looping commands ..
$chartohandle = $reference{$last_char - $i};
Et voil! Nice stream of single characters.
22-Jul-2002 11:26
PHP's double-quoted strings are inherently ill-featured - they will be a problem especially with computed code like in /e-evals with preg_replace.
bash and perl follow the widely accepted rule that all backslashes will escape the nextfollowing char, and nonalpha-chars will always get printed there as themselves whereas (the unescaped chars might have special meaning in regex). Anyway, it is a great way to just escape all nonalpha chars that you uncertain about whether they have special meaning in some places, and ye'll be sure they will get printed literal.
Furthermore, note that \{ sequence is not mentioned in the escape-char table! You'll get to know about it only "complex (curly) syntax". This can even more be a problem with evals, as they behave rather flaky like it _cannot_ be accomodated for computed code. Try all variants of `echo "hello \{\$world}"` removing one or more of the chars in the \{\$ part - have fun!
