الفرق بين المراجعتين لصفحة: «PHP/Types/string»

من موسوعة حسوب
< PHP‏ | Types
ط استبدال النص - 'PHP/Types/resource' ب'PHP/resource'
ط استبدال النص - 'PHP/Types/type-juggling' ب'PHP/type juggling'
سطر 592: سطر 592:
يمكن تحويل القيم إلى سلسلة نصية باستخدام الصيغة <code>(string)</code> أو الدالة <code>[[PHP/Function/strval|strval()‎]]</code>، وتتحول السلسلة النصية تلقائيًا في التعابير البرمجية عند الحاجة، على سبيل المثال عند استعمال <code>echo</code> أو دوال الطباعة، أو عند مقارنة متغير بسلسلة نصية.
يمكن تحويل القيم إلى سلسلة نصية باستخدام الصيغة <code>(string)</code> أو الدالة <code>[[PHP/Function/strval|strval()‎]]</code>، وتتحول السلسلة النصية تلقائيًا في التعابير البرمجية عند الحاجة، على سبيل المثال عند استعمال <code>echo</code> أو دوال الطباعة، أو عند مقارنة متغير بسلسلة نصية.


يمكنك مراجعة أقسام [[PHP/Types|الأنواع]] و<nowiki/>[[PHP/Types/type-juggling|التعامل مع الأنواع]] ودالة <code>[[PHP/Function/settype|settype()‎]]</code> للمزيد من المعلومات.
يمكنك مراجعة أقسام [[PHP/Types|الأنواع]] و<nowiki/>[[PHP/type juggling|التعامل مع الأنواع]] ودالة <code>[[PHP/Function/settype|settype()‎]]</code> للمزيد من المعلومات.


تتحول [[PHP/boolean|القيمة المنطقية]] <code>TRUE</code> إلى السلسلة النصية <code>"1"</code> وأما <code>FALSE</code> فتتحول إلى <code>""</code> (سلسلة نصية فارغة)، وهذا يسمح لك بالتحويل من الجهتين بين المتغيرات المنطقية وقيم السلاسل النصية.
تتحول [[PHP/boolean|القيمة المنطقية]] <code>TRUE</code> إلى السلسلة النصية <code>"1"</code> وأما <code>FALSE</code> فتتحول إلى <code>""</code> (سلسلة نصية فارغة)، وهذا يسمح لك بالتحويل من الجهتين بين المتغيرات المنطقية وقيم السلاسل النصية.

مراجعة 03:34، 4 أبريل 2018

السلسلة النصية هي سلسلة من الأحرف، إذ يكون كل حرف ممثلًا ببايت، ولذلك فإن PHP تدعم مجموعةً من 256 حرفًا فقط ولا تقدم دعمًا لمحارف يونيكود، راجع "تفاصيل نوع البيانات string" للمزيد من المعلومات.

ملاحظة: بدءًا من الإصدار 7.0.0، لم تعد هنالك قيودٌ حول طول السلسلة النصية على منصات 64 بت، أما بالنسبة لمنصات 32 بت وفي النسخ القديمة، يمكن أن يصل حجم السلسلة النصية إلى 2 جيجا بايت (2147483647 بايت).

البنية العامة

يمكنك تعريف السلسلة النصية بأربع طرائق مختلفة:

علامتا اقتباس مفردتان

أبسط طريقة لتعريف سلسلة نصية هي وضعها داخل علامة اقتباس واحدة (الرمز ').

يمكنك تهريب رمز علامة الاقتباس باستعمال الخط المائل (أي الرمز \) وذلك إذا أردت استخدامها في السلسلة النصية، أما لاستخدام رمز الخط المائل الخلفي فيمكن تكراره مرتين متتاليتين (\\)، أما بالنسبة لبقية حالات رمز الخط المائل والتي تستخدم لمعاني خاصة مثل ‎\r أو ‎\n، ستُعدّ حروفًا عاديةً وستظهر كما هي.

ملاحظة: على عكس صيغة علامتَي الاقتباس المزدوجتين وصيغة heredoc، لن تعمل المتغيرات وسلاسل التهريب للأحرف الخاصة عند وضعها بين علامتَي اقتباس مفردتين.

<?php
echo 'this is a simple string';

echo 'You can also have embedded newlines in 
strings this way as it is
okay to do';

// Arnold once said: "I'll be back"
echo 'Arnold once said: "I\'ll be back"';

// You deleted C:\*.*?
echo 'You deleted C:\\*.*?';

// You deleted C:\*.*?
echo 'You deleted C:\*.*?';

// This will not expand: \n a newline
echo 'This will not expand: \n a newline';

// Variables do not $expand $either
echo 'Variables do not $expand $either';
?>

علامتا اقتباس مزدوجتان

سيفسر PHP سلاسل التهريب (escape sequences) التي تشير إلى محارف خاصة إذا كانت السلسلة محاطة بعلامتي اقتباس مزدوجتين.

سلسلة التهريب المعنى
‎‎\n سطر جديد (linefeed أي LF أو 0x0A في ASCII)
‎‎\r محرف العودة إلى بداية السطر (carriage return أي CR أو 0x0D في ASCII)
‎‎\t مسافة جدولة أفقية (horizontal tab أي HT أو 0x09 في ASCII)
‎‎\v مسافة جدولة رأسية (vertical tab أي VT أو 0x0B في ASCII) (منذ PHP 5.2.5)
‎‎\e تهريب (escape أي ESC أو 0x1B في ASCII) (منذ PHP 5.4.4)
‎‎\f الانتقال إلى صفحة جديدة (form feed أي FF أو 0x0C في ASCII) (منذ PHP 5.2.5)
\\ خط مائل خلفي
‎‎\$ رمز الدولار
‎‎\"‎‎ علامة اقتباس مزدوجة
‎‎\[0-7]{1,3}‎‎ سلسلة محارف تُطابِق تعبيرًا نمطيًا (regular expression) الذي يُمثِّل عددًا في نظام العد الثماني؛ لكن هذه السلسلة ستتجاوز البايت (بصمت، مثلًا: ‎"\400" === "\000"‎)
‎‎\x[0-9A-Fa-f]{1,2}‎‎ سلسلة محارف تُطابِق تعبيرًا نمطيًا (regular expression) الذي يُمثِّل رقمًا في نظام العد الست عشري (hexadecimal).
‎‎\u{[0-9A-Fa-f]+}‎‎ سلسلة محارف تُطابِق تعبيرًا نمطيًا الذي يُمثِّل رمز يونيكود والذي سيُعرَض كمحرف يونيكود في ترميز المحارف UTF-8 (منذ PHP 7.0.0).

عند تهريب أي محارف أخرى، فستطبع كما هي بما  استخدام علامتَي الاقتباس المفردتين

من أهم مميزات استخدام علامة اقتباس المزدوجة هي أن أسماء المتغيرات ستفسر وسيظهر محتواها.

صيغة heredoc

الطريقة الثالثة لتعريف السلاسل النصية هي باستخدام صيغة heredoc: تضع بالبداية المعامل >>>، ثم تضع مُعرِّفًا (identifier)، ثم تضع سطرًا جديدًا ثمتبدأ كتابة السلسلة النصية، وفي نهاية تضع المعرف نفسه مجددًا لتحديد نهاية السلسلة النصية.

يجب أن يبدأ معرف النهاية في أول عمود في السطر، وعليه أن يتبع نفس قواعد أسماء كأي لافتات (label) في PHP: يجب أن يحتوي على حروف وأرقام إضافةً إلىرمز الخط السفلي (underscore) فقط ويجب ألّا يبدأ المُعرِّف بمحرف غير رقمي أو خط سفلي.

تنبيه: يجب ألّا يحتوي سطر معرف النهاية على أيّة أحرف أخرى سوى الرمز الفاصلة المنقوطة (;)، وهذا يعني أنَّه لا يجوز أن يبدأ السطر بمسافة، ولا يُسمَح بوجود مسافات قبل أو بعد رمز الفاصلة المنقوطة، إضافةً إلى ذلك، من المهم معرفة أن أول حرف قبل معرِّف الإغلاق يجب أن يكون سطرً جديدً كما هو مُعرَّف حسب نظام التشغيل المستخدم، والتي هي ‎\n في أنظمة يونكس بما في ذلك Mac OS X، ويجب أن يُتبَع محدد الإغلاق بسطر جديد.

إذا لم تُتّبَع القاعدة ولم يكتب سطر معرف الإغلاق بشكل صحيح، فلن يُعدّ كمعرّف إغلاق، وستستمر لغة PHP بالبحث عنه، وإذا لم يجده قبل نهاية الملف الحالي، فسيظهر خطأ في السطر الأخير.

المثال 1: مثال خطأ

<?php
class foo {
    public $bar = <<<EOT
bar
    EOT;
}
// لا تضع مسافات قبل المعرّف
?> 


المثال 2: مثال خطأ
<?php
class foo {
    public $bar = <<<EOT
bar
EOT;
}
?>

لم يكن ممكنًا استخدام صيغة heredoc لتهيئة خصائص الأصناف لكن بدءًا من الإصدار 5.3 من PHP، أصبح بالإمكان استخدام صيغة heredoc في هذه الحالة إذا كانت تحتوي على متغيرات.

يتصرف نص heredoc تمامًا مثل السلاسل النصية المحاطة بعلامتَي اقتباس مزوجتين، لكن دون استخدامها لإحاطة السلسلة النصية، وهذا يعني أنه لا حاجة لتهريب علامة الاقتباس المزدوجة، لكن يزال بالإمكان استخدام جدول التهريب في الأعلى، وستفسر المتغيرات الموجودة في السلسلة النصية، لكن يجب الانتباه عند التعبير عن متغيرات معقدة داخل صيغة heredoc كما في السلاسل النصية.

المثال 3: مثال عن استخدام علامات الاقتباس ضمن السلاسل النصية في صيغة heredoc

<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* أمثلة أكثر تعقيدًا، مع متغيرات. */
class foo
{
    var $foo;
    var $bar;

    function __construct()
    {
        $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;
?>

مخرجات المثال السابق هي:

My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A

من الممكن استخدام صيغة heredoc لتمرير البيانات إلى الدوال.

المثال 4: استخدام صيغة heredoc لتمرير وسيط إلى دالة

<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>

من الممكن بدءًا من PHP 5.3.0 تهيئة المتغيرات الساكنة (static vaiables) والخاصيات والثوابت التابعة للأصناف باستخدام صيغة heredoc:

المثال 5: استخدام صيغة heredoc لتهيئة القيم الساكنة

<?php
// متغيرات ساكنة
function foo()
{
    static $bar = <<<LABEL
Nothing in here...
LABEL;
}

// خاصيات وثوابت تابعة لصنف
class foo
{
    const BAR = <<<FOOBAR
Constant example
FOOBAR;

    public $baz = <<<FOOBAR
Property example
FOOBAR;
}
?>

بدءًا من الإصدار PHP 5.3.0، أصبح من الممكن وضع معرف heredoc بين علامتَي اقتباس مزدوجتين:

المثال 6: استخدام علامتي اقتباس مزدوجتين في heredoc

<?php
echo <<<"FOOBAR"
Hello World!
FOOBAR;
?>

صيغة nowdoc

صيغة nowdoc تشابه صيغة heredoc، لكنها أقرب إلى سلوك السلاسل النصية المحاطة بعلامتَي اقتباس مفردتين (بينما صيغة heredoc أقرب إلى سلوك السلاسل النصية المحاطة بعلامتَي اقتباس مزدوجتين) فلن يُفسَّر أي محرف تهريب أو متغير، وهذه البنية مثالية لتضمين شيفرة PHP أو نص كبير دون الحاجة إلى تهريبه.

تُعرّف صيغة nowdoc باستخدام المعامل >>> كما في صيغة heredoc، لكن المُعرِّف الذي يلي ذاك المعامل سيكون محاطًا بعلامتَي اقتباس مفردتين، مثلًا: ‎<<<'EOT'‎، جميع القواعد الأخرى التي تنطبق على صيغة heredoc تنتطبق أيضًا على صيغة nowdoc؛ خصوصًا تلك التي تتعلق بطريقة إضافة مُعرِّف الإغلاق.

المثال 7: مثال عن استخدام علامات الاقتباس ضمن السلاسل النصية في صيغة nowdoc

<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;

/* أمثلة أكثر تعقيدًا، مع متغيرات. */

class foo
{
    public $foo;
    public $bar;

    function __construct()
    {
        $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 not print a capital 'A': \x41
EOT;
?>

مخرجات المثال السابق:

My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41

المثال 8: بيانات ثابتة

<?php
class foo {
    public $bar = <<<'EOT'
bar
EOT;
}
?>

ملاحظة: أضيف دعم صيغة nowdoc في الإصدار PHP 5.3.0.

تفسير قيم المتغيرات

تُفسَّر المتغيرات في السلاسل النصية عندما تُعرَّف تلك السلاسل باستخدام علامتَي اقتباس مزدوجتين أو صيغة heredoc.

هنالك صيغتان لتعريف المتغيرات ضمن السلاسل النصية: صيغة بسيطة وصيغة معقدة، الصيغة البسيطة أسهل وأكثر انتشارًا، وهي توفر طريقةً لتضمين متغير أو مصفوفة أو خاصية أحد الكائنات في السلاسل النصية بأقل جهد.

أما الصيغة المُعقّدة فتمتاز أنَّه تُحيط التعبير بأقواسٍ معقوفة {}.

الصيغة البسيطة

إذا وُجد رمز الدولار $، فسيأخذ المُفسِّر أقصى عدد من المحارف التي تلي رمز $ ليكوِّن اسمًا صالحًا للمتغير. ضمّن اسم المتغير بين أقواس معقوفة لتحديد نهاية الاسم.

<?php
$juice = "apple";

echo "He drank some $juice juice.".PHP_EOL;
// التعبير الآتي غير صحيح، لوجود حرف زائد بعد اسم المتغير

echo "He drank some juice made of $juices.";
// التعبير الآتي صحيح، لتحديد نهاية التعبير بإحاطته بقوسين معقوفين

echo "He drank some juice made of ${juice}s.";
?>

مخرجات المثال السابق:

He drank some apple juice.
He drank some juice made of .
He drank some juice made of apples.

وبنفس الطريقة يمكن تفسير فهرس المصفوفة أو خاصية كائن؛ ففي المصفوفات، سيحدد القوس المربع نهاية الفهرس وتطبق نفس قواعد المتغيرات البسيطة على خصائص الكائن.

المثال 9: الصيغة البسيطة

<?php
$juices = array("apple", "orange", "koolaid1" => "purple");

echo "He drank some $juices[0] juice.".PHP_EOL;
echo "He drank some $juices[1] juice.".PHP_EOL;
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;

class people {
    public $john = "John Smith";
    public $jane = "Jane Smith";
    public $robert = "Robert Paulsen";

    public $smith = "Smith";
}

$people = new people();

echo "$people->john drank some $juices[0] juice.".PHP_EOL;
echo "$people->john then said hello to $people->jane.".PHP_EOL;
echo "$people->john's wife greeted $people->robert.".PHP_EOL;
echo "$people->robert greeted the two $people->smiths."; // لن تعمل
?>

مخرجات المثال السابق:

He drank some apple juice.
He drank some orange juice.
He drank some purple juice.
John Smith drank some apple juice.
John Smith then said hello to Jane Smith.
John Smith's wife greeted Robert Paulsen.
Robert Paulsen greeted the two .

دعمت مؤشرات الرقمية السالبة (أي رقم الفهرس سالب) منذ الإصدار PHP 7.1.0.

المثال 10: مؤشرات رقمية سالبة

<?php
$string = 'string';
echo "The character at index -2 is $string[-2].", PHP_EOL;
$string[-3] = 'o';
echo "Changing the character at index -3 to o gives $string.", PHP_EOL;
?>

مخرجات المثال السابق:

The character at index -2 is n.
Changing the character at index -3 to o gives strong.

لأي شيء آخر أكثر تعقيدًا، يجب عليك استخدام الصيغة المعقدة.

الصيغة المعقدة (الأقواس المعقوفة)

لا تسمى معقدة لأن الصياغة معقدة بل لأنها تسمح لك باستخدام تعابير معقدة ضمنها.

يمكن تضمين أي متغير عادي أو عنصر مصفوفة أو خاصية كائن (التي يمكن تمثيلها على شكل سلسلة نصية) باستخدام هذه الصيغة، كل ما عليك فعله هو كتابة التعبير بنفس الطريقة التي تستخدمها خارج السلاسل النصية، ومن ثم ضع حولها { و }.

ولّما كان من غير الممكن تهريب المحرف } فلن يتعرف مُفسّر اللغة على الصيغة المُعقّدة إذا لم يأتِ المحرف $ مباشرةً بعد القوس }، لذا استخدم الصيغة ‎{\$‎ للحصول على السلسلة النصية ‎{$‎ في المخرجات.

بعض الأمثلة لتوضيح الفكرة:

<?php
// إظهار جميع الأخطاء
error_reporting(E_ALL);

$great = 'fantastic';

// لن تعمل، المخرجات هي
// { fantastic}
echo "This is { $great}";

// تعمل، المخرجات
// This is fantastic
echo "This is {$great}";

// تعمل
echo "This square is {$square->width}00 centimeters broad."; 


// تعمل، المفاتيح داخل علامات الاقتباس تعمل فقط باستخدام صياغة الأقواس المعقوفة
echo "This works: {$arr['key']}";


// تعمل
echo "This works: {$arr[4][3]}";

// التعبير الآتي خطأ، لنفس السبب الذي يكون فيه التعبير
// $foo[bar]
// خطأ، لأنَّ فهرس المصفوفة ليس محاطًا بعلامتَي اقتباس.
// بعبارةٍ أخرى: سيعمل التعبير الآتي، لكن المُفسِّر سيبحث عن قيمة الثابت
// foo
// أولًا، ثم سيرمى خطأٌ من النوع
// NOTICE (undefined constant)
echo "This is wrong: {$arr[foo][3]}"; 

// تعمل. عند استخدام المصفوفات متعددة الأبعاد، استخدم دائمًا الأقواس المعقوفة حول المصفوفات عندما تكون داخل السلاسل النصية.
echo "This works: {$arr['foo'][3]}";

// تعمل
echo "This works: " . $arr['foo'][3];

echo "This works too: {$obj->values[3]->name}";

echo "This is the value of the var named $name: {${$name}}";

echo "This is the value of the var named by the return value of getName(): {${getName()}}";

echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";

// لن تعمل، المخرجات
// This is the return value of getName(): {getName()}
echo "This is the return value of getName(): {getName()}";
?>

من الممكن أيضًا الوصول إلى خاصية صنف باستعمال متغيرات داخل السلسلة النصية باستخدام هذه الصيغة.

<?php
class foo {
    var $bar = 'I am bar.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo "{$foo->$bar}\n";
echo "{$foo->{$baz[1]}}\n";
?>

مخرجات المثال السابق:

I am bar.
I am bar.

ملاحظة: تعمل الدوال و متغيرات الصنف الساكنة (static class variables) وثوابت الصنف (class constants) ضمن الصيغة {$} منذ الإصدار PHP 5، ومع ذلك، ستفسر القيمة التي تم الوصول إليها على أنها اسم متغير في المجال (scope)الذي عُرّفت السلسلة النصية فيه. لا يمكن استخدام قوسين معقوفين مفردين {} للوصول إلى القيم المُعادة من الدوال أو قيم ثوابت الصنف أو متغيرات صنف الثابتة.

<?php
// إظهار جميع الأخطاء
error_reporting(E_ALL);

class beers {
    const softdrink = 'rootbeer';
    public static $ale = 'ipa';
}

$rootbeer = 'A & W';
$ipa = 'Alexander Keith\'s';

// سيعمل، المخرجات:
// I'd like an A & W
echo "I'd like an {${beers::softdrink}}\n";

// سيعمل أيضا، المخرجات
// I'd like an Alexander Keith's
echo "I'd like an {${beers::$ale}}\n";
?>

الوصول إلى المحارف المكوِّنة للسلسلة النصية وتغييرها

يمكن الوصول إلى المحارف داخل السلسلة النصية وتعديلها بتحديد الحرف المطلوب (الترقيم يبدأ من الصفر) بعد اسم السلسلة النصية باستخدام الأقواس المربعة (التي تُستعمَل للوصول إلى عناصر المصفوفات) كما في هذا المثال ‎$str[42]‎. أي يمكننا أن نعدّ السلسلة النصية على أنها مصفوفةٌ من المحارف.يمكنك استخدام الدالتين substr()‎ و substr_replace()‎ عندما ترغب في استخراج أو تبديل أكثر من محرف واحد.

ملاحظة: دعمت الفهارس السالبة في السلاسل النصية منذ الإصدار PHP 7.1.0، إذ تُحدَّد الإزاحة (offset) من نهاية السلسلة النصية. وسابقًا، كانت تظهر أخطاء E_NOTICE عند محاولة الوصول إلى محارف السلاسل النصية باستخدام الفهارس السالبة (ستنتج سلسلة نصية فارغة) والخطأ E_WARNING عند الكتابة عليها (ستُترك السلسلة النصية كما هي).

ملاحظة: يمكن الوصول إلى السلاسل النصية باستخدام القوسين المعقوفين مثل ‎$str{42}‎.

تنبيه: إذا كتبت في مكان خارج حدود السلسلة النصية فستُملأ السلسلة النصية بمسافات، الأنواع التي لا تكون أعدادًا صحيحةً ستحوّل إلى أعداد صحيحة، يؤدي استخدام الإزاحة من نوع غير صحيح إلى رمي خطأ من النوع E_NOTICE، ولن يُستخدَم سوى الحرف الأول من السلسلة النصية المُسندة.

بدءًا من PHP 7.1.0، يرمي إسناد سلسلة نصية فارغة خطأً (fetal error)، لكنه كان سابقًا يؤدي إلى إسناد بايت فارغ (NULL byte).

تنبيه: دخليًا، السلاسل النصية في PHP هي مصفوفات تتألف من بايتات، لذلك، فإن الوصول أو تعديل سلسلة نصية باستخدام الأقواس المربعة الخاصة بالمصفوفات ليس آمنًا مع المصفوفات متعددة البايتات، ويجب استخدامها فقط مع السلاسل النصية الموجودة في ترميز بايت واحد مثل ISO-8859-1.

ملاحظة: سيظهر خطأ عند استخدام معامل الفهرس دون تحديد قيمة للفهرس فيه على السلاسل النصية من الإصدار PHP 7.1.0، لكن كان يحوّل بصمت إلى مصفوفة فيما سبق.

المثال 11: أمثلة عن بعض السلاسل النصية

<?php
// الحصول على أول حرف من السلسلة النصية
$str = 'This is a test.';
$first = $str[0];

// الحصول على الحرف الثالث من السلسلة النصية
$third = $str[2];

// الحصول على الحرف الأخير من السلسلة النصية
$str = 'This is still a test.';
$last = $str[strlen($str)-1]; 

// تعديل الحرف الأخير من السلسلة النصية
$str = 'Look at the sea';
$str[strlen($str)-1] = 'e';

?>

بدءًا من الإصدار PHP 5.4، إزاحات السلسلة النصية يجب أن تكون أعدادًا صحيحةً أو أعدادُا صحيحةً على شكل سلسلة نصية، وإلا فستظهر رسالة خطأ، في السابق، كانت تحوّل الإزاحات مثل "foo" إلى 0.

المثال 12: الفرق بين الإصدار 5.3 و 5.4 من PHP

<?php
$str = 'abc';

var_dump($str['1']);
var_dump(isset($str['1']));

var_dump($str['1.0']);
var_dump(isset($str['1.0']));

var_dump($str['x']);
var_dump(isset($str['x']));

var_dump($str['1x']);
var_dump(isset($str['1x']));
?>

مخرجات المثال السابق في php 5.3:

string(1) "b"
bool(true)
string(1) "b"
bool(true)
string(1) "a"
bool(true)
string(1) "b"
bool(true)

مخرجات المثال السابق في php 5.4:

string(1) "b"
bool(true)

Warning: Illegal string offset '1.0' in /tmp/t.php on line 7
string(1) "b"
bool(false)

Warning: Illegal string offset 'x' in /tmp/t.php on line 9
string(1) "a"
bool(false)
string(1) "b"
bool(false)

ملاحظة: إن الوصول إلى المتغيرات من الأنواع الأخرى (التي لا تشمل المصفوفات أو الكائنات التي تستخدم واجهات [interfaces] المناسبة) باستخدام [] أو {} سيُعيد القيمة NULL.

ملاحظة: أضافت PHP 5.5 دعم الوصول إلى الحروف ضمن السلسلة النصية الحرفية باستعمال [] أو {}.

دوال ومعاملات مهمة

يمكن دمج السلاسل النصية باستخدام معامل النقطة . ولن يعمل معامل الجمع + في هذه الحالة، اطلع على معاملات السلاسل النصية للمزيد من المعلومات.

يوجد العديد من الدوال المفيدة للتعامل مع السلاسل النصية، ويمكنك الإطلاع على قسم "دوال السلسلة النصية" للدوال العامة، أو قسم" دوال التعابير النمطية" (regular expression functions) أو قسم "دوال التعابير النمطية متوافقة مع Perl" لوظائف متقدمة للبحث والاستبدال.

توجد أيضًا دوال للمعالجة السلاسل النصية التي تكون على شكل URL، ودوال لتشفير وفك تشفير السلاسل النصية (mcrypt و mhash).

التحويل إلى سلسلة نصية

يمكن تحويل القيم إلى سلسلة نصية باستخدام الصيغة (string) أو الدالة strval()‎، وتتحول السلسلة النصية تلقائيًا في التعابير البرمجية عند الحاجة، على سبيل المثال عند استعمال echo أو دوال الطباعة، أو عند مقارنة متغير بسلسلة نصية.

يمكنك مراجعة أقسام الأنواع والتعامل مع الأنواع ودالة settype()‎ للمزيد من المعلومات.

تتحول القيمة المنطقية TRUE إلى السلسلة النصية "1" وأما FALSE فتتحول إلى "" (سلسلة نصية فارغة)، وهذا يسمح لك بالتحويل من الجهتين بين المتغيرات المنطقية وقيم السلاسل النصية.

عند تحويل عدد صحيح أو عدد عشري إلى سلسلة نصية، فيُمثَّل ذلك بالعدد نصيًا (بما في ذلك الجزء الأسي من العدد العشري)، فالأعداد العشرية يمكن تحويلها باستخدام الصيغة العلمية (exponential notation) (مثلًا: 4.1E+6).

ملاحظة: تُعرّف نقطة العدد العشري في محليّة السكربت (the script's locale) (الفئة LC_NUMERIC) ويمكنك مراجعة دالة setlocale()‎ للمزيد من المعلومات.

تتحول المصفوفات إلى السلسلة النصية "Array"، ولذلك لا يمكنك استخدام echo و print لطباعة محتوى المصفوفة، لكن لعرض عنصر واحد، فاستخدم الصيغة echo $arr['foo']‎. انظر أدناه للحصول على نصائح حول عرض محتويات المصفوفة بأكملها.

يجب عليك استخدام الدالة العضو ‎__toString لتحويل الكائنات إلى سلاسل نصية.

تتحول الموارد دائمًا إلى سلاسل نصية باستخدام البنية "Resource id #1" إذ إنَّ 1 هو رقم المورد المعين من قبل PHP وقت التشغيل، لكن البنية الدقيقة لهذه السلسلة النصية لا يمكن الاعتماد عليها وقابلة للتغيير، وستكون فريدة دائما لمورد معين في وقت تشغيل السكربت (مثال طلبية ويب أو عملية CLI) ولن يعاد استخدامها. يمكنك استخدام دالة get_resource_type()‎ للحصول على نوع المورد.

تتحول القيمة NULL دائمًا إلى سلسلة نصية فارغة.

كما ذكرنا أعلاه، التحويل المباشر لمصفوفة أو كائن أو مورد إلى سلسلة نصية لا يقدم أية معلومات مفيدة حول قيمته، ويمكنك الإطلاع على دوال print_r()‎ و var_dump()‎ للمزيد من الوسائل الفعالة لمعاينة محتوى هذه الأنواع.

يمكنك تحويل أغلب قيم PHP إلى سلاسل نصية للتخزين الدائم، وهذه الطريقة تسمى serialization، وتنفذ من قبل دالة serialize()‎ وإذا بني محرك PHP مع دعم WDDX، فيمكن تحويل قيم PHP إلى صيغة XML.

تحويل السلاسل النصية إلى أرقام

عند مقارنة سلسلة نصية في سياق رقمي، نوع وقيمة النتيجة ستحدد كما يلي.

إذا لم تحتوِ السلسلة النصية على الحروف '.' أو 'e' أو 'E' والقيمة الرقمية الموجدة في السلسلة النصية لا تتجاوز حدود العدد الصحيح (كما عُرِّفت في PHP_INT_MAX)، فستقارن السلسلة النصية كعدد صحيح، وفي جميع الحالات الأخرى، ستقارن كعدد عشري.

القيمةُ الرقميةُ موجودةٌ في أول جزءٍ من السلسلة النصية، لكن إذا بدأت السلسلة النصية ببيانات رقمية صالحة، فستُستخدم هذه القيمة وإلا ستكون القيمة 0 (صفر).

البيانات الرقمية الصالحة هي إشارة اختيارية متبوعة برقم واحد أو أكثر (يمكن أن يحتوي اختياريًا على النقطة العشرية) متبوعة اختياريًا بأس. الأس هو الحرف ‘e’ أو ‘E’ متبوعًا برقم أو أكثر.

<?php
$foo = 1 + "10.5";                // عدد كسري 11.5
$foo = 1 + "-1.3e3";              // عدد كسري -1299
$foo = 1 + "bob-1.3e3";           // عدد صحيح 1
$foo = 1 + "bob3";                // عدد صحيح 1
$foo = 1 + "10 Small Cows";       // عدد صحيح 11
$foo = 4 + "10.2 Little Cows";    // عدد كسري 14.2
$foo = "10.0 cows " + 1;          // عدد كسري 11
$foo = "10.0 cows " + 1.0;        // عدد كسري 11 
?>

للمزيد من المعلومات حول هذا التحويل، راجع صفحة دليل يونكس strtod(3)‎.

لاختبار الأمثلة الموجودة في هذا القسم، انسخ والصق الأمثلة وضع السطر التالي لتعرف ما الذي يجري:

<?php
echo "\$foo==$foo; type is " . gettype ($foo) . "<br />\n";
?>

لا تتوقع الحصول على رمز المحرف من خلال تحويله إلى عدد صحيح كما في لغة السي C، يمكنك استخدام الدالتين ord()‎ و chr()‎ للتحويل بين رموز ASCII و الحروف.

تفاصيل نوع البيانات String

السلسلة النصية في لغة PHP هي مصفوفات تتألف من بايتات مع عدد صحيح يشير إلى طول الذاكرة المؤقتة (buffer)، ولا تملك أية معلومات حول كيفية تحويل هذه البايتات إلى حروف، إذ تُترَك هذه  الوظيفة إلى المبرمج.

لا توجد حدود حول حجم السلسلة النصية، ويسمح لك باستخدام البياتات ذات القيمة 0 (بايتات فارغة "NUL Bytes") في أي مكان في السلسلة النصية (لكن، بعض الدوال المذكورة في الدليل ليست «أمنة ثنائيًا – Binary Safe»، فقد تمرر السلاسل النصية إلى مكتبات تتجاهل البيانات بعد البايت الفارغ NUL byte).

طبيعة نوع السلاسل النصية يشرح سبب عدم وجود نوع "byte" منفصل في PHP، إذ إنَّ السلاسل النصية في PHP تأخذ هذا الدور، الدوال التي تعيد بيانات غير نصية، على سبيل المثال، البيانات التي ستُقرأ من مقبس (socket) ستُعيد سلاسل نصية.

البعض يتساءل كيف تُرمَّز السلاسل النصية إذا كانت PHP لا تملي ترميزًا معينًا للسلاسل النصية، فعلى سبيل المثال هل الحرف "á" يساوي "‎‎\xE1" (في ISO-8859-1) أو  "‎‎\xC3\xA1" (في UTF-8, C form) أو "‎‎\x61\xCC\x81" (في UTF-8, D form) أو أي تمثيل آخر؟ والإجابة هي أن السلسلة النصية سترمز حسب ترميز السكربت، فإذا كان السكربت مكتوب بترميز ISO-8859-1 فسترمز البيانات بنفس الترميز.

الدوال التي تعمل على النصوص تضع بعض الافتراضات حول ترميز النص لكي تعمل بشكلٍ صحيح، ولسوء الحظ، يوجد تباين كبيرة في هذه المسألة في دوال PHP:

  • بعض الدوال تفترض أن السلسلة النصي مرمزة بترميز أحادي البايت (single-byte encoding)، لكنها لن تحتاج إلى تفسير هذه البايتات كمحارف مُحدَّدة مثال ذلك هو الدوال: substr()‎ أو strpos()‎ أو strlen()‎ أو strcmp()‎. يمكنك التفكير في هذه الدوال على أنها تتعامل مع الذاكرة المؤقتة (buffer)، أي أنها تعمل على البايبات وزَيَحان البايتات (byte offsets).
  • يمكن تمرير الترميز لبعض الدوال، وبعضها يستخدم الترميز الافتراضي إذا لم تعطى هذه المعلومة، مثل دالة htmlentities()‎ وأغلب هذه الدوال موجودةً في الإضافة mbstring.
  • تستخدم بعض الدوال إعدادات المحليّة (locale، راجع الدالة setlocale()‎) لكنها تتعامل على بايت في كل مرة (byte-by-byte) كما في دوال strcasecmp()‎ و strtoupper()‎ و ucfirst()‎. وهذا يعني أنها لا تعمل إلا على ترميزات البايت الواحد (single-byte) طالما أن الترميز يتطابق مع المحلية (locale)، على سبيل المثال الدالة strtoupper("á")‎ قد تعيد "Á" إذا كانت إعدادات المحليّة صحيحة وكان المحرف á مرمّزًا في بايت واحد. لكن إذا رمّز باستعمال UTF-8 فلن تُعاد النتيجة الصحيحة وستكون السلسلة النصية الناتجة تالفة وفقًا لإعدادات المحلية.
  • أخيرا، قد تفترض الدوال أن السلسلة النصية تستخدم ترميز معين – في العادة UTF-8، وهذا حال أغلب دوال الإضافة intl و PCRE (في الحالة الأخيرة، عند استخدام المعدل u)، على الرغم من أن هذا يعود لأغراض خاصة، لكن الدالة utf8_decode()‎ تفترض أنَّ الترميز المستخدم في السلسلة النصية هو ترميز UTF-8 والدالة utf8_encode()‎ تفترض ترميز ISO-8859-1.

الخلاصة هي أنَّه يجب الانتباه إلى تجنب استخدام الدوال التي لن تعمل وستخرب البيانات عند كتابة البرامج باستخدام ترميز يونيكود (Unicode) واستخدام الدوال التي تعمل جيدًا ( لإضافات intl و mbstring)، ومع ذلك، استخدام الدوال التي تتعامل مع ترميزات Unicode هي البداية فقط، فمهما كانت الدالة التي توفرها اللغة، يجب عليك معرفة مواصفات Unicode، فعلى سبيل المثال، افتراض أن هنالك حروف كبيرة وصغيرة فقط هو افتراضٌ خطأ.

مصادر