# زبان های اسکریپتی > PHP > تاپیک های آموزشی و دنباله دار >  ویژگی های مخفی زبان PHP

## محسن شامحمدی

php_logo-300x150.pngبا سلام خدمت دوستان
داشتم چرخی توی وب می زدم که با یه تاپیک خیلی جالب با عنوان ویژگی های مخفی php برخورد کردم و از خوندنش بسیار لذت بردم.
مناسب دیدم که مطالب رو ترجمه کنم تا عزیزان استفاده کافی رو ببرند.
به این خاطر می گن نکات مخفی.چون خیلی از برنامه نویس های باتجربه php هم از این نکات خبر ندارند.
سعی می کنم هر نکته رو توی یک پست بزنم.
لطفا  برای تشکر فقط از دکمه تشکر سایت استفاده کنید.

----------


## محسن شامحمدی

*standard class

*بجای استفاده از آرایه ها برای نگهداری یه سری اطلاعات و attribute ها به این شکل:
$person = array();
$person['name'] = 'bob';
$person['age'] = 5;
می تونید از کلاس استاندارد به این شکل استفاده کنید:
$person = new stdClass();
$person->name = 'bob';
$person->age = 5;


و اینطوری کدی تمیزتر و خواناتر داشته باشید.بعنوان مثال:
$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

----------


## محسن شامحمدی

*مقدار برگشتی از فایل include شده

*فایل های include شده می تونن مستقیما یک مقدار برگشتی داشته باشن(شبیه توابع) که توی یک متغیر قرار بگیرن

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

مزیتش نسبت به اینکه یه ارایه باشه توی فایل و با include شدن فایل اون آرایه هم include بشه(با global scope) خب بحث تمیزتر بودن کد و قاطی نشدن با آرایه های همنام ه.

----------


## محسن شامحمدی

*متغیر متغیر

*$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

یعنی با گذاشتن دوتا علامت دلار, php می ره سراغ متغیر بعدیش

*همینطور برای توابع*
function foo() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!
البته این ویژگی باعث ناخوانا شدن کد می شه و احتمال خطا رو زیاد می کته

----------


## محسن شامحمدی

*توابع با آرگومان های نامحدود!

*درسته که نحوه تعریف کردن توابع و ورودی هاش بطور استاندار به این شکله:
function test($a1,$a2,$an(}
//some codes here
{
ولی با تابع func_get_args() می شه کارهای جادویی کرد.

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

----------


## محسن شامحمدی

*کار با فایل ها و صفحات خارج از سایت

*نیاز به محتوای یک صفحه html دارید؟
$str = file_get_contents('http://example.com');

یا با فایل خاصی کار دارید:
$fp = fopen('http://example.com/filename.ext');

مثل هر فایل دیگه ای handle گرفته شد و می شه با توابع فایلی روش کار کرد.

یا مثلا می خواید سایز یک عکس رو که روی یک سرور ftp هست بدست بیارید:
$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

حتی می تونید کدهای php رو از روی سرورهای دیگه include کنید! :شیطان:  (این کار بشدت خطرناکه و اصلا توصیه نمی شه!)

----------


## محسن شامحمدی

*درست کردن متغیر از خانه های یک آرایه!*
$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");
extract($var_array);
echo "$color, $size, $shape";



و برعکس این کار
یعنی ساخت آرایه ای که نام متغیرها کلیدش باشه و مقدار متغیرها مقادیرش:
$city  = "San Frabarnamenevisco";
$state = "CA";
$event = "SIGGRAPH";

$location_vars = array("city", "state");

$result = compact("event", "nothing_here", $location_vars);
print_r($result);
که خروجی می شه:


```
Array(
    [event] => SIGGRAPH
    [city] => San Frabarnamenevisco
    [state] => CA )
```

----------


## محسن شامحمدی

*Range
*این تابع مختص php نیست و خیلی هم ویژگی مخفی ای نیست.ولی توی تمیزبودن کدنویسی خیلی جالبه

به جای:
for ($i=0; $i < $x; $i++) { 
    // code...
}

می تونیم بنویسیم:
foreach (range(0, 12) as $number) {
    // ...
}

یا مثلا به این شکل:

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}

----------


## محسن شامحمدی

*خط تیره در نام متغیرها*
class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

----------


## محسن شامحمدی

*رشته ای با هر کارکتر
*
echo <<<EOM  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

کد sql
$sql = <<<SQL
select *
  from $tablename
 where id in [$order_ids_list]
   and product_name = "widgets"
SQL;این ویژگی توی نوشتن کدهای html و همچنین کدهای sql خیلی کاربرد داره(بجای echo کردن توی متغیر بذاریش).

----------


## محسن شامحمدی

*دسترسی به رشته شبیه یک آرایه

*به رشته ها می شه مثل آرایه ها دسترسی پیدا کرد
$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"

----------


## MMSHFE

> حتی می تونید کدهای php رو از روی سرورهای دیگه include کنید! (این کار بشدت خطرناکه و اصلا توصیه نمی شه!)


ضمن تشکر از تاپیک خوبی که ایجاد کردین، دقت کنید که راهنمایی اشتباه نکنید. در حالت عادی و با تنظیمات پیشفرض چنین کاری امکان نداره. شما وقتی فایل یک سرور دیگه رو میخونید، اگه اون فایل PHP باشه شما نتیجه اجرای اون رو (درست مثل وقتی که توی مرورگر صداش بزنید) میبینید یعنی کدها روی اون سرور اجرا شدن و شما خروجی HTML که تولید کرده رو خواهید داشت و برای مثال نمیتونید متغیرهایی که اونجا تعریف شده رو توی اسکریپت خودتون داشته باشین. ازطرفی اگه توی تنظیمات php.ini توی سرورتون allow_url_include رو فعال کنید، میتونید از این قابلیت استفاده کنید که فوق العاده خطرناکه (همونطور که اشاره کردین) چون ممکنه یک نفر بیاد تو اسکریپتش یک کد مخرب بنویسه که وقتی شما اون رو include میکنید روی هاست شما اجرا میشه! اگه نمیخواین اجازه بدین اسکریپتهای شما توسط سایتهای دیگه ضمیمه بشن هم کافیه اسکریپتهای خودتون رو توی یک پوشه بگذارین و با فایل htaccess. جلوی دسترسی غریبه ها رو بگیرین:
ORDER DENY,ALLOW
DENY FROM ALL
ALLOW FROM 127.0.0.1
این روش توی فریمورکهای معروف (مثل Yii) استفاده شده و فقط فایل ورودی سایت که بهش میگن Entry Script و فایلهای عادی مثل CSS و JS و... بیرون هستن و تمام اسکریپتهای دیگه توی پوشه protected قرار گرفتن.

----------


## محسن شامحمدی

*یافتن راهنمایی و مثال از یک تابع با سرعت نوز!
*در مورد هر تابعی که سوال داشته باشید و طرز کارش رو بخواید.به سادگی هر چه تمام:
http://php.net/function

----------


## محسن شامحمدی

*اجرای کد php از یک رشته متنی!
*class foo {  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();


یا 

$clazz = "class SomeClass { var \$value = 'somevalue'; function show() { echo get_class(\$this);}}"; 

eval($clazz); 

$instance = new SomeClass; 

// Here output 'somevalue'; 
echo $instance->value; 

echo "<br>"; 

//Here output 'someclass' 
$instance->show();

----------


## محسن شامحمدی

*خروج از چندین لایه با استفاده از break n

*همونطوری که همه می دونید می شه با break از یک for,while,switch در اومد.ولی break می تونه عدد بگیره که از چند لایه خارج بشه!

$i = 0;
while (++$i) {
    switch ($i) {
    case 5:
        echo "At 5<br />\n";
        break 1;  /* Exit only the switch. */
    case 10:
        echo "At 10; quitting<br />\n";
        break 2;  /* Exit the switch and the while. */
    default:
        break;
    }
}

----------


## محسن شامحمدی

*عملگر "خفه شو"!*
خیلی از مواقع کدی نوشتیم که کار می کنه ولی warning هم داره و توی خروجی چاپ می شه.
بهترین راه برای اینطور مواقع استفاده از عملگر @ هستش.
/* Intentional file error */
$my_file = @file ('non_existent_file') or
    die ("Failed opening file: error was '$php_errormsg'");

// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.

پ.ن:Five reasons why the shut-op operator (@) should be avoided

پ.ن: کد باید اینقدر خوب نوشته بشه و انواع شرایط با توابعی مثل isset,empty چک بشه که نیازی به استفاده از این عملگر نباشه.چون حتی خطاهای بحرانی رو هم نادیده می گیره!

----------


## محسن شامحمدی

افزودن مقدار به آرایه به سادگی هر چه تمام:
$my_array = array();
$my_array[] = 'first element';
$my_array[] = 'second element'

----------


## محسن شامحمدی

*اجرای کدهای php در لینوکس شما.
*زبان های اسکریپتی و shell همیشه یکی از قدرت های لینوکس بوده و هستند.
اگر خیلی روی shell تسلط نداشته باشید.با این تکنیک می تونید خیلی از کارهاتون رو با زبان php اجرا کنید.
فقط کافیه فایل اسکریپتتون به این شکل شروع بشه.
البته آدرسش بستگی به محل نصب php روی سیستمتون داره.


```
#!/usr/bin/php5
<?php
```

پ.ن: توی کامنت ها گفتن اگه اینو بذارید


```
#!/usr/bin/env php
```

خود لینوکس ادرس php رو واستون پیدا می کنه!

----------


## محسن شامحمدی

*استفاده از عملگرهای منطقی


*همه با and,or آشنا هستند که چطور کار می کنه.می شه توی کدنویسی هم از اینا استفاده کرد!
TRUE AND print 'Hello';
FALSE OR print 'World';

// Prints "HelloWorld";

مثال پیچیده تر و کاربردی
// Complex example...
User::logged_in() or die('Not allowed');
User::is_admin() AND print 'Admin Area';

----------


## محسن شامحمدی

*چاپ مقادیر آرایه ها درون یک رشته

*به جای
$newVar = $ar['foo']['bar'];
echo "Array value is $newVar";

$newVar = $obj->foo->bar;
echo "Object value is $newVar";

می شه نوشت:
echo "Array value is {$ar['foo']['bar']}";
echo "Object value is {$obj->foo->bar}";
تمیزتر و قشنگ تر!

----------


## محسن شامحمدی

*Stream Handlers

*با این امکان می تونید به سادگی انواع فایل ها رو با فرمت های مختلف بخونید و بنویسید.
برای مثال برای فایل Excel :
کلاسش

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);

کلی stream handler دیگه توسط دوستان نوشته شده که می تونید از اینجا ببینید

----------

