تبدیل Type داده ها به یکدیگر Casting (مقاله)

پرسیده شده
فعالیت 1585 روز پیش
دیده شده 1108 بار
1

در جلسات قبل متغیرها را توضیح دادیم و گفتیم متغیرها در PHP بطور اتوماتیک و با توجه به مقدارش، نوع میپذیرد.
در مقالات قبلی، گفتیم PHP جزو زبان های Loosely Typed میباشد و نیازی نیست نوع متغیر را مشخص کنیم. نوع متغیرها، از روی نوع مقداری که در آن assign شده، بصورت داینامیک مشخص میشود.
برای مثال به دستورات زیر توجه کنید:

<?php
$bool = true;
echo gettype($bool) . '<br>'; // boolean

//-------------------------------//

$integer = 1;
echo gettype($integer) . '<br>'; // integer

//-------------------------------//

// float, double or real are the same datatype in PHP
$float = 1.2;
echo gettype($float) . '<br>'; // double

//-------------------------------//

$string = "7learn";
echo gettype($string) . '<br>'; // string

//-------------------------------//

$array = [];
echo gettype($array) . '<br>'; // array

//-------------------------------//

$null = null;
echo gettype($null) . '<br>'; // NULL

 

تا اینجا مطلب جدیدی نگفته ایم و فقط مروری برگذشته داشته ایم. همانطور که میبینید، نوع متغیرها بر اساس مقداریست که در آنها ریخته شده است.
با توجه به این توضیح، شرایط دیگری را در مثال های زیر بررسی میکنیم:

<?php
$a = 1 + 2; // 3
echo gettype($a) . '<br>'; // integer

//-------------------------------//

$b = 1 + 1.0; // 2.0
echo gettype($b) . '<br>'; // double

//-------------------------------//

$c = 2 * 5; // 10
echo gettype($c) . '<br>'; // integer

//-------------------------------//

$d = 2 * 1.; // 2.
echo gettype($d) . '<br>'; // double

//-------------------------------//

$e = 2 / 1; // 2
echo gettype($e) . '<br>'; // ineteger

//-------------------------------//

$f = 2 / 1.; // 2.
echo gettype($f) . '<br>'; // double

خط 2 $a = 1 + 2; : ابتدا 1 + 2 محاسبه میگردد و مقدار 3 در داخل متغیر $a ریخته میشود. بنابراین نوع $aبرابر است با Integer.
خط 7 $b = 1 + 1.0; : بدیهی است که وقتی یک عدد صحیح را با یک عدد اعشاری جمع میکنید، حاصلجمع آنها مقداری اعشاری باشد. مثلا 1 + 1.1 = 2.1 خواهد بود. پس 1 + 1.0 = 2.0 خواهد بود. بنابراین نوع $b برابر است با Float.

خط 12 $c = 2 * 5; :  حاصلضرب دو عدد صحیح برابر خواهد بود با یک عدد صحیح.
خط 17 $d = 2 * 1.; : حالا اگر یک عدد صحیح با یک عدد اعشاری ضرب شود حاصلضرب آن یک عدد اعشاری خواهد بود. (تقسیم هم بهمین ترتیب خواهد بود.)

میبینید که با همان تعریف اول حاکم است و نوع متغیر از روی نوع مقدارش معین میشود.
حالا اگر رشته ای نسبت به یک عدد، سنجیده شود(مثل جمع بین رشته و عدد یا مقایسه ی بین رشته و عدد)، آن رشته تبدیل به مقادیر عددی خواهد شد.
رشته ای که با عدد شروع شود، مقدارش برابر همان عدد است و اگر با عدد شروع نشود، آن رشته، مقدارش 0 در نظر گرفته میشود.
مثال های زیر تمام حالت ها را نشان داده است:

<?php
$a = "1" + '2'; // 3
echo gettype($a) . '<br>'; // integer

//-------------------------------//

$b = 1 + "2."; // 3.
echo gettype($b) . '<br>'; // double

//-------------------------------//

$c = 2 * '7learn'; // 14
echo gettype($c) . '<br>'; // integer

//-------------------------------//

$d = 2 * '7.learn'; // 14.
echo gettype($d) . '<br>'; // double

//-------------------------------//

$e = 2 + '0.learn'; // 2.
echo gettype($e) . '<br>'; // double

//-------------------------------//

$f = 2 * 'learn'; // 0
echo gettype($f) . '<br>'; // integer

//-------------------------------//

$g = 'true' + true; // 1
echo gettype($g) . '<br>'; // integer

//-------------------------------//

$h = 'mohsen2' + '4.2movahed'; // 4.2
echo gettype($h) . '<br>'; // double

خط 2 $a = "1" + '2'; : رشته ی "1" با عدد شروع شده است پس تبدیل به مقدار عددی 1 میشود و رشته ی "2" هم به همین صورت و حاصلجمع این دو عدد برابر است با مقدار 3 که یک عدد integer است.

نکته: توجه داشته باشید که در عبارت $str = '1 + 2'; یا $str = "1 + 2"; (دابل کوت و سینگل کوت فرقی نمیکند) هیچ عملیات جمعی صورت نمیگیرد. چون علامت جمع(+) در داخل رشته آمده است و بعنوان یک کاراکتری از رشته شناخته میشود.

خط 12 $c = 2 * '7learn'; : عبارت 7learn با عدد 7 شروع شده است پس این رشته به عدد صحیح 7 تبدیل خواهد شد.
خط 17 $d = 2 * '7.learn'; : عبارت 7.learn با عدد 7. شروع شده است پس این رشته با عدد اعشاری 7.0 تبدیل خواهد شد.
خط 27 $f = 2 * 'learn'; : عبارت learn با عددی شروع نشده است پس این رشته به عدد صحیح 0 تبدیل خواهد شد.

 

 

اما CAST چیست؟ cast هیچ چیزی نیست جز تبدیل شدن یک نوع به نوع دیگر. هیچ پیچیدگی خاصی هم ندارد.
مثلا تبدیل integer به float یا تبدیل string به integer و ...

در مثال های بالا، دیدید که PHP بصورت اتوماتیک چطور انواع را به یکدیگر تبدیل میکند.
ممکن است زمانی بخواهید نوع یک مقدار را صراحتا اعلام کنید کافیست آن مقدار را به نوع مورد نظر cast کنید.
به مثال زیر توجه کنید:

<?php
$a = (boolean) 22; // 1
echo gettype($a) . '<br>'; // boolean

//-------------------------------//

$b = (integer) $a; // 1
echo gettype($b) . '<br>'; // integer

//-------------------------------//

$c = (float) 'learn'; // 0.0
echo gettype($c) . '<br>'; // double

//-------------------------------//

$d = (string) true; // 1
echo gettype($d) . '<br>'; // string

//-------------------------------//

$e = (array) 12; // [0 => 12]
echo gettype($e) . '<br>'; // array

//-------------------------------//

$f = (unset) 'mohsen movahed';
echo gettype($f) . '<br>'; // NULL

همانطور که میبینید، نوعی که میخواهیم به آن تبدیل شود را در داخل پرانتز قرار میدهیم.

 

 

* تبدیل به Boolean:
برای اینکه مقداری را صراحتا به boolean تبدیل کنید، از (bool) یا (boolean) استفاده کنید. البته در اکثر موارد به این تبدیل نیازی نخواهید داشت. چون هر قسمتی که نیاز به boolean داشته باشد، بصورت اتوماتیک این عمل تبدیل انجام میشود.
بطور مثال در عبارت if($a == true) نوع $a هر چه که هست، بصورت اتوماتیک به boolean تبدیل میشود. یعنی انگار نوشته اید if((bool) $a == true)

مقادیر زیر، زمانیکه به boolean تبدیل میشوند، برابر FALSE هستند:

<?php
$a = (bool) false; // false
//-------------------------------//
$b = (bool) 0; // false
//-------------------------------//
$c = (bool) ""; // false
//-------------------------------//
$d = (bool) "0"; // false
//-------------------------------//
$e = (bool) []; // false
//-------------------------------//
$f = (bool) null; // false

var_dump($f); // boolean false

در بقیه ی موارد، مقادیر به TRUE تبدیل خواهند شد. (حتی نوع Resource)
به مثال های زیر، با دقت نگاه کنید:

<?php
var_dump((bool) "");        // bool(false)
//-----------------
var_dump((bool) 1);         // bool(true)
//-----------------
var_dump((bool) -1);        // bool(true)
//-----------------
var_dump((bool) "foo");     // bool(true)
//-----------------
var_dump((bool) 1.2e5);     // bool(true)
//-----------------
var_dump((bool) array(22)); // bool(true)
//-----------------
var_dump((bool) array());   // bool(false)
//-----------------
var_dump((bool) "false");   // bool(true)

توجه: اعداد منفی هم به TRUE تبدیل خواهند شد.(هر عددی غیر از صفر)

 

* تبدیل به Integer:
برای تبدیل نوعی به integer، از (int) یا (integer) استفاده کنید. همچنین برای تبدیل به integer میتوانید از تابع intval() استفاده کنید.
یکی از قسمت هایی که این تبدیل میتونه به دردتون بخوره، زمانیه که مثلا مقداری از سمت کاربر دریافت میکنید و میخواهید حتما نوع آن عددی باشد و حتی اگر یک رشته فرستاده شده بود(قانون تبدیل رشته ها در مثال های بالا گفته شده)، در هر شرایط به integer تبدیل شود، اینجا میتوانید عمل casting را انجام دهید. اگرچه در اکثر موارد به این تبدیل نیازی پیدا نخواهید کرد. چون این تبدیل بصورت اتوماتیک انجام خواهد شد.
بطور مثال در عبارت if($a == 24) تبدیل if((int) $a == 24) بصورت اتوماتیک انجام میشود.

به مثال زیر توجه کنید:

<?php
$string = 'mohsen';
echo intval($string); // 0

//-----------------------------//

$a = 5;
$b = 2;
echo (int)($a / $b); // 2

خط 9: در مثال بالا، ابتدا تقسیم انجام میشود و سپس حاصل تقسیم یعنی 2.5 تبدیل به integer میشود.

نکته: تبدیل مقدار بولین FALSE به integer برابر 0 خواهد بود و TRUE برابر عدد 1 میباشد.

توجه: اعداد اعشاری ناشناخته را به integer تبدیل نکنید:

<?php
echo (int) ( (0.1 + 0.7) * 10 ); // 7 !!!

اگر روی کاغذ حساب کنیم، (0.1 + 0.7) * 10 = 8.0 خواهد بود و 8.0 وقتی تبدیل به integer شود، قسمت صحیح آن یعنی 8 جدا میشود.
پس انتظار میرود که جواب 8 چاپ شود ولی 7 (!!!) چاپ شده است.

چرا 7: اعدادی مثل 0.1 و 0.7 در مبنای 2، مقدار دقیقی ندارند و حاصل عبارت ( (0.1 + 0.7) * 10 ) چیزی شبیه 7.9999999999999991118... خواهد بود.
حالا وقتی این عدد تبدیل به integer میشود، فقط مقدار صحیح آن جدا میشود. بنابراین مقدار 7 چاپ میشود.

اما اگر به integer تبدیل نکنید، عبارت echo ( (0.1 + 0.7) * 10 ); مقدار 8 را چاپ میکند.
چرا 8: تعداد رقم های اعشار زیاد است و اعداد اعشاری از لحاظ تعداد ارقام دارای محدودیت هستند و نمیتوان تمام این ارقام را نشان داد، بنابراین آن مقدار ارقام مجاز نگه داشته میشوند(مثلا 14 رقم) و مابقی ارقام حذف میشوند و عدد باقی مانده، گرد میشود.

نکته: در فایل php.ini میتوانید با تغییر مقدار precision مقدار دقت عدد اعشاری را مشخص کنید.
مقدار پیش فرض در این فایل precision = 14 میباشد. بنابراین اگر عدد اعشاری، بیشتر از 14 رقم باشد، با توجه به توضیح چند خط بالاتر، آن عدد گرد خواهد شد.

حالا با توجه به نکاتی که در این قسمت گفتیم، عدد 7.9999999999999991118... بیشتر از 14 رقم میباشد، بنابراین 14 رقم مجاز، نگه داشته میشوند و مابقی ارقام حذف میشوند و در نهایت، عدد باقیمانده گرد خواهد شد. در اینجا به 8 گرد میشود.
برای تمرین میتوانید این عبارت را تست کنید و تعداد ارقامش رو کم کنید و دوباره اجرا بگیرید: echo 7.9999999999999991118;

سؤال: چرا اعداد اعشاری به مبنای 2 تبدیل میشوند؟
پاسخ: هر چیزی، چه عدد، چه تصویر، چه متن، چه ... در کامپیوتر بصورت مبنای 2 یا همان باینری ذخیره میشود.

+ وقتی نوع resource به integer تبدیل میشود، نتیجه ی تبدیل، آیدی resource میباشد.
+ قوانین تبدیل string به integer هم در اوایل این جلسه، گفته شد.

 

* تبدیل به Float:
برای تبدیل، از (float) یا (double) یا (real) استفاده کنید. همچنین برای تبدیل نوعی به Float میتوانید از تابع floatval() استفاده کنید.
تبدیل string به float هم در اوایل این جلسه، گفته شد.

 

* تبدیل به String:
برای تبدیل به string، از (string) یا تابع strval() استفاده کنید.
string هم بمانند بقیه ی type ها در جایی که نیاز به string باشد، بصورت اتومات به string تبدیل خواهد شد.
برای مثال وقتی از توابع echo یا print استفاده میکنید، مقدار داده شده بصورت اتومات تبدیل به string میشود.

نکات:
1. تبدیل Boolean به String: ثابت TRUE به "1" تبدیل خواهد شد و ثابت FALSE به یک رشته ی خالی "" تبدیل میشود.
2. تبدیل Integer (یا Float) به String: عددی مانند 123 به "123" و عددی مانند 12.3 به "12.3" تبدیل خواهد شد.
3. تبدیل Array به String: یک آرایه همیشه به رشته ی "Array" تبدیل میشود. یعنی اگر یک آرایه بنام $array داشته باشید و آنرا بصورت echo $array; چاپ کنید، عبارت Array چاپ خواهد شد(البته بهمراه یک Notice). بخاطر اینکه echo و print نمیتوانند محتوای کامل یک آرایه را نشان بدهند. برای همین در زمان چاپ مقادیر آرایه، باید همراه با نام آرایه، ایندکس آرایه را هم ذکر کنید.

<?php
$array = [1, 2, 3];
echo $array; // Array
// Notice: Array to string conversion

 

4. تبدیل Resource به String: یک resource همیشه به رشته ای با ساختار Resouce id #1 تبدیل خواهد شد. 1 شماره ایست که PHP در زمان اجرا به آن resource اختصاص داده است. این آیدی یونیک میباشد.

<?php
echo $a = fopen('file1', 'r'); // Resource id #3
echo $b = fopen('file2', 'r'); // Resource id #4

 

5. تبدیل Null به String: به یک رشته خالی "" تبدیل میشود.

 

* تبدیل به Array:
با استفاده از (array) میتوانید انواع داده را به array تبدیل کنید.
نکته ای که وجود دارد، هر یک از انواع integer ، float ، string ، boolean ، resource وقتی به یک آرایه تبدیل میشوند، به آرایه ای با یک عنصر (با ایندکس 0) تبدیل میشوند.

 

* تبدیل به Resource:
با توجه به مقادیری که این نوع از داده میپذیرد، تبدیل به resource نامعقول است.

 

* تبدیل به NULL:
برای تبدیل، از (unset) استفاده کنید.
در این تبدیل مقدار به NULL تبدیل میشود. همچنین اگر یک متغیر را بصورت (unset) $a بنویسید، مقدار $a برابر با NULL میشود و حذف نمیشود. ولی اگر از تابع unset() استفاده کنید و بنویسید unset($a) در اینجا متغیر $a حذف خواهد شد.

نکته: عمل cast به NULL در PHP 7.2.0 منسوخ شده است.

 

نکته ی پایانی: برای تبدیل انواع داده به یکدیگر، میتوانید از تابع settype() هم استفاده کنید:

<?php
$a = '4mohsen'; // string
$b = true;      // boolean

settype($a, 'integer'); // $a is now 4   (integer)
settype($b, 'string');  // $b is now '1' (string)

echo gettype($a) . '<br>'; // integer
echo gettype($b) . '<br>'; // string

بقیه ی انواع داده ها را به همین ترتیب، میتوان تبدیل کرد.

فایل پیوست

محسن موحد
محسن موحد

2 دی 98