PDA

View Full Version : ویژگی های مخفی زبان PHP



محسن شامحمدی
دوشنبه 26 آبان 1393, 10:18 صبح
125789
با سلام خدمت دوستان
داشتم چرخی توی وب می زدم که با یه تاپیک خیلی جالب با عنوان ویژگی های مخفی php (http://stackoverflow.com/questions/61401/hidden-features-of-php) برخورد کردم و از خوندنش بسیار لذت بردم.
مناسب دیدم که مطالب رو ترجمه کنم تا عزیزان استفاده کافی رو ببرند.
به این خاطر می گن نکات مخفی.چون خیلی از برنامه نویس های باتجربه php هم از این نکات خبر ندارند.
سعی می کنم هر نکته رو توی یک پست بزنم.
لطفا برای تشکر فقط از دکمه تشکر سایت استفاده کنید.

محسن شامحمدی
دوشنبه 26 آبان 1393, 10:28 صبح
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.";

محسن شامحمدی
دوشنبه 26 آبان 1393, 10:37 صبح
مقدار برگشتی از فایل 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) خب بحث تمیزتر بودن کد و قاطی نشدن با آرایه های همنام ه.

محسن شامحمدی
دوشنبه 26 آبان 1393, 10:46 صبح
متغیر متغیر


$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!
البته این ویژگی باعث ناخوانا شدن کد می شه و احتمال خطا رو زیاد می کته

محسن شامحمدی
دوشنبه 26 آبان 1393, 10:52 صبح
توابع با آرگومان های نامحدود!

درسته که نحوه تعریف کردن توابع و ورودی هاش بطور استاندار به این شکله:

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);

محسن شامحمدی
دوشنبه 26 آبان 1393, 10:59 صبح
کار با فایل ها و صفحات خارج از سایت

نیاز به محتوای یک صفحه 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 کنید!:شیطان: (این کار بشدت خطرناکه و اصلا توصیه نمی شه!)

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:23 صبح
درست کردن متغیر از خانه های یک آرایه!

$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array);
echo "$color, $size, $shape";



و برعکس این کار
یعنی ساخت آرایه ای که نام متغیرها کلیدش باشه و مقدار متغیرها مقادیرش:

$city = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";

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

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

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

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:29 صبح
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";
}

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:34 صبح
خط تیره در نام متغیرها

class style
{
....
function set_bg_colour($c)
{
$this->{'background-color'} = $c;
}
}

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:40 صبح
رشته ای با هر کارکتر


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 کردن توی متغیر بذاریش).

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:44 صبح
دسترسی به رشته شبیه یک آرایه

به رشته ها می شه مثل آرایه ها دسترسی پیدا کرد

$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
دوشنبه 26 آبان 1393, 11:46 صبح
حتی می تونید کدهای 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 قرار گرفتن.

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:48 صبح
یافتن راهنمایی و مثال از یک تابع با سرعت نوز!
در مورد هر تابعی که سوال داشته باشید و طرز کارش رو بخواید.به سادگی هر چه تمام:
http://php.net/function

محسن شامحمدی
دوشنبه 26 آبان 1393, 11:56 صبح
اجرای کد 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();

محسن شامحمدی
دوشنبه 26 آبان 1393, 12:04 عصر
خروج از چندین لایه با استفاده از 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;
}
}

محسن شامحمدی
دوشنبه 26 آبان 1393, 12:10 عصر
عملگر "خفه شو"!
خیلی از مواقع کدی نوشتیم که کار می کنه ولی 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 (http://derickrethans.nl/five-reasons-why-the-shutop-operator-should-be-avoided.html)

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

محسن شامحمدی
دوشنبه 26 آبان 1393, 12:13 عصر
افزودن مقدار به آرایه به سادگی هر چه تمام:

$my_array = array();
$my_array[] = 'first element';
$my_array[] = 'second element'

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

#!/usr/bin/php5
<?php

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

#!/usr/bin/env php
خود لینوکس ادرس php رو واستون پیدا می کنه!

محسن شامحمدی
دوشنبه 26 آبان 1393, 12:40 عصر
استفاده از عملگرهای منطقی


همه با 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';

محسن شامحمدی
دوشنبه 26 آبان 1393, 12:42 عصر
چاپ مقادیر آرایه ها درون یک رشته

به جای

$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}";
تمیزتر و قشنگ تر!

محسن شامحمدی
دوشنبه 26 آبان 1393, 13:29 عصر
Stream Handlers

با این امکان می تونید به سادگی انواع فایل ها رو با فرمت های مختلف بخونید و بنویسید.
برای مثال برای فایل Excel :
کلاسش (http://www.phpclasses.org/browse/package/1919.html)


$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 دیگه توسط دوستان نوشته شده که می تونید از اینجا ببینید (http://www.phpclasses.org/blog/post/74-A-PHP-killer-feature--Streams-abstraction.html)