PHP: Array Tricks Part 1

ამ პოსტს ჩემი ერთი მეგობრის თხოვნით ვწერ რომელთანაც გუშინ საუბარი მქონდა PHP – ს მასივებსა და for/foreach კონსტრუქციებთან მუშაობის შესახებ.

მასივები PHP – ს ერთერთი ყველაზე ძლიერი და განვითარებული მხარეა და შესაბამისად შეიცავს უამრავ ნიუანსს. ხშირ შემთხვევაში ასეთი ნიუანსები გამოუცდელი თუ გამოცდილი პროგრამისტების მიერ იგნორირებული რჩება და ამის შედეგად ვღებულობთ საკმაოდ დაუხვეწავ და სრულიად ზედმეტ კოდს.

ამ პოსტში მაქსიმალურად შევეცდები გადმოვცე ის დეტალები რაც PHP – სთან წლების მანძილზე მუშაობით შევიძინე და იმედი მაქვს რომ ეს ინფორმაცია თქვენთვისაც სასარგებლო იქნება. მაშ ასე შევუდგეთ საქმეს :)

ფუნქციიდან მასივის დაბრუნება

ხშირად მინახავს ასეთი ფუნქციები რომლებიც გარკვეული პირობის შესაბამისად აბრუნებენ ან მასივს ან null მნიშვნელობას(ასეთი შეცდომა მეც არაერთხელ მომსვლია და ამაში ტრაგიკული არაფერია). რეალურად ეს აბსოლუტურად ზედმეტი და არასაჭირო ქმედებაა რადგან შემდგომ დამატებითი კოდის წერის საჭიროებას იწვევს. ასეთ შემთხვევაში უმჯობესია ფუნქციამ დააბრუნოს უბრალოდ ცარიელი მასივი და არა null. მაგალითისათვის განვიხილოთ შემდეგი კოდი:

1
2
3
function getArray($flag) { 
   return $flag == true ? array(1, 2, 3) : null;
}

ეს ფუნქცია პარამეტრის მნიშვნელობიდან გამომდინარე დააბრუნებს ან მასივს ან null მნიშვნელობას. ახლა შევეცადოთ მისი გამოყენება:

1
2
3
4
5
6
//თუ ფუნქციამ დააბრუნებს მასივს გამოვბეჭდოთ მისი მნიშვნელობები
if ($array = getArray(true)) {
   foreach($array as $key => $value) {
      printf('key = %s and value = %s<br />', $key, $value);
   }
}

ნჩვენებ კოდში ვიძახებთ getArray(true) ფუნქციას და ვანიჭებთ მას $array ცვლადს, რადგან ეს ხდება IF პირობის ოპერატორში მნიშვნელობის შემოწმებაც მომენტალურად ხდება და მისი არსებობის შემთხვევაში მასივის ელემენტები გამოიბეჭდება ეკრანზე.

დამეთანხმებით რომ ძალიან ჩვეულებრივი და ტიპიური შემთხვევაა. მაგრამ ისეთ შემთხვევაში თუ უბრალოდ მასივის ელემენტების გამობეჭდვა გვესაჭიროება და მეტი არაფერი ეს დაწერილი კოდი სავსებით ზედმეტია. ნაჩვენები მაგალითI შეგვიძლია გადავაკეთოთ შემდეგნაირად:

1
2
3
4
5
6
7
8
9
//ეს ფუნქცია ნებისმიერ შემთხვევაში აბრუნებს მასივს
function getArray($flag) { 
   return $flag == true ? array(1, 2, 3) : array();
}

$array = getArray(true);
foreach($array as $key => $value) {
   printf('key = %s and value = %s<br />', $key, $value);
}

ამ კოდის შესრულების შემდეგ აბსოლუტურად იდენტურ შედეგს მივიღებთ, თუმცა ერთი ძალიან მნიშნველოვანი განსხვავებით, რომ, IF პირობის გამოყენება სრულიად აცილებულია თავიდან რადგან ფუნქცია ნებისმიერ შემთხვევაში აბრუნებს მასივს, ხოლო ასეთ შემოწმებას თავად foreach ახდენს ავტომატურად.

ახლა ბუნებრივად უნდა დაიბადოს შეკითხვა თუ რა მოვიგეთ განსაკუთრებული? აქ კიდევ ერთ ნიუანსზე შევაჩერებ თქვენს ყურადღებას და getArray ფუნქციის გამოყენების რამდენიმე სასარგებლო დეტალს შევეხები. ამისათვის საჭიროა კოდში შევიტანოთ პატარა ცვლილება:

1
2
3
4
5
6
7
8
9
10
11
//ეს ფუნქცია ნებისმიერ შემთხვევაში აბრუნებს მასივს
function getArray($flag) {
   //ფუნქციის გამოძახების ინდიკატორი
   echo ('invoked<br />'); 
   return $flag == true ? array(1, 2, 3) : array();
}

//getArray() ფუნქციის გამოძახება foreach კონსტრუქციაში
foreach(getArray(true) as $key => $value) {
   printf('key = %s and value = %s<br />', $key, $value);
}

ამ კოდის შესრულების შემდეგ მივიღებთ ანალოგიურ შედეგს, თუმცა უნდა აღინიშნოს, რომ, ამჯერად getArray() ფუნქცია გამოიძახება პირდაპირ foreach() კონსტრუქციაში და არა მის გარეთ. ეს ძალიან მნიშნელოვანი დეტალია რადგან ბევრ პროგრამისტს რატომღაც შეცდომად მიაჩნია ფუნქციის ამგვარი გამოძახება. რატომ? რადგან ფუნქცია გამოიძახება foreach – ში მიიჩნევა რომ მისი გამოძახება მოხდება იმდენჯერ რამდენი იტერაციაც იქნება ციკლში. თუმცა ეს ბუნებრივია ასე არ არის რასაც ზემოთ ნაჩვენები მაგალითიც ამტკიცებს.

ამ მაგალითიდან გამომდინარე უნდა გაგიჩნდეთ კიდევ ერთი შეკითხვა: და თუ მაინც მინდა მივანიჭო ცვლადს ფუნქციის მიერ დაბრუნებული მნიშნველობა? არც ეს არისპრობლემა:

1
2
3
4
//getArray() ფუნქციის დაბრუნებული მნიშვნელობის მინიჭება
foreach($array = getArray(true) as $key => $value) {
   printf('key = %s and value = %s<br />', $key, $value);
}

რატომღაც ცვლადზე ფუნქციის მიერ დაბრუნებული მნიშვნელობის ეს მეთოდიც ხშირად არის იგნორირებული, თუმცა ასეთი მინიჭება სრულებით დასაშვებია და ყოველგვარი პრობლემების გარეშე მუშაობს.

და ასევე ბონუსის სახით გეტყვით რომ თუ მაინც გვესაჭიროება IF პირობის შესრულება ისე როგორც ეს ნაჩვენები იყო პირველ მაგალითში არც ამაზეა არანაირი პრობლემა :D

პირველ მაგალითში ნაჩვენები პირობა, ანუ:

if ($array = getArray(false)) {
   //rest of code here
}

იმუშავებს ერთნაირად მიუხედავად იმისა ფუნქცია დააბრუნებს ცარიელ მასივსა თუ null მნიშვნელობას რადგან PHP fale, null, array() და 0 მნიშვნელობის ასეთი შემოწმების შემთხვევაში ყოველთვის დააბრუნებს false – ს.

ტეგები:

8 Responses to “PHP: Array Tricks Part 1”

  1. LRuby says:

    კაია. :)

    აი კიდევ ერთი საინტერესო რამ მასივებზე, ანუ შევადაროთ ორი მასივი ერთმანეთს და გავიგოთ რამდენი პროცენტი დამთხვევა მეორე მასივში:

    $array_1 = array('a','b','c','d', 'a', '5', 4, 5, 7, 1, 0, 2, 9);
    
    $array_2 = array('b','d', 8, 1);
    
    $non_matches = array_diff($array_1, $array_2);
    
    $inaccuracy = round((sizeof($non_matches)/sizeof($array_1))*100, 2);
    $accuracy = 100-$inaccuracy;
    
    echo 'array2 contains '.$accuracy.'% of the content that array_1 contains';
    
  2. @LRuby

    გავაერთიანე შენი პოსტები :)

    კოდის დაწერა როცა დაგჭირდება PRE ტეგი გამოიყენე ;)

  3. სოსო, “აძინოკი ვოლკად” თუ წერ, მართალი ხარ – ყველა ფუნქციამ ან რეალური მასივი ან ცარიელი მასივი რომ აბრუნოს, ძალიან კარგია, მაგრამ რეალობას თუ გაითვალისწინებ, ან რაიმე ფრეიმვორკს თუ იყენებ, ან უბრალოდ სხვის კოდს ან თუნდაც PHP ბიბლიოთეკებს, სადაც უამრავია მსგავსი შემთხვევა – დაზღვეული არასოდეს არ ხარ რომ ვიღაც ნულს არ დაგიბრუნებს და სახეს არ აახევს შენ მოდულს.

    შესაბამისად, ყველაზე ნაღდი რჩევაა, დაგინებით foreach-ის გამოყენებამდე შეამოწმო რომ ნამდვილად არაცარიელ მასივთან გაქვს საქმე:

    if (is_array($es_chemisa) && sizeof($es_chemisa)>0) {
      foreach ($es_chemisa as $key => $val) {
        // dalshe rogorc textshia
      }
    }
    

    კი, მაგრად ტეხავს ზედმეტი ორი ხაზის წერა, რამდენი ფორიჩი დაგჭირდება, მაგრამ იმდენ თავის ტკივილს აგაშორებს დროთა განმავლობაში, რომ ნამდვილად ღირს. მით უმეტეს რომ ყველა თავმოყვარე IDE-ს აქვს კოდის ტემპლეიტების ფუნქცია, და აუცილებელი არაა ხელით კრეფა.

  4. @ირაკლი

    რასაც შენ ამბობ აბსოლუტურად მართალი ხარ არასოდეს არ ხარ მაგისგან დაზღვეული, მაგრამ რომელი ფრეიმვორკიც არ უნდა გამოიყენო შენი ფუნქციების წერა მაინც ხომ გიწევს?

    თანაც პოსტში მარტო მაგ საკითხზე არ არის ლაპარაკი და ერთერთი დეტალია ეგ :)

    სხვა მხრივ გეთანხმები ყველაფერში ;)

    P.S.

    ისე შენი კოდის ამ ნაწილში(ნუ მაგ კონკრეტულ მაგალითს ეხება):

    if (is_array($es_chemisa) && sizeof($es_chemisa)>0) {
    

    ეს ნაწილი: && sizeof($es_chemisa)>0 სრულიად ზედმეტია, მასივი თუ არის მაგ შემოწმებას foreach კონსტრუქცია თავად გაგიკეთებს ;)

  5. LRuby says:

    იოსებ როცა მოიცლი ერთი კაი სტატიას (შენ რო იცი ისეთს :>) ხო შემოგვთავაზებ კეშირებაზე Tips & Trick-ის პონტში :) ანუ გაგვიზიარე რაიმე “ხრიკები” თუ გაქვს.
    ამასწინათ დამჭირდა რაღაცაში ტემპლეიტ პარსინგის დროს, ცოტა ჩალიჩის შემდეგ ერთი ორი ტრიუკი მეც შევიმუშავე :)

  6. გიორგი says:

    ამ მაგალითებისთვის Rapid PHP 2008 გამომადგება?

  7. სახელი says:

    სალამი აქურობას
    რა მაინტერესებს ვედზებ ისეტ სკრიპტს რომელიც სიახლების დადებისას საიტის დაბლა გაკეტებს ავტომატურად გვერდებს.
    და კიდე რეგისტრაცია როგორ დავაყენო საიტზე მაგის ცალკე სკრიპტი არის?
    ვიარე ამ პჰპზე ვერაპერი ვერ მასწავლეს დიდი::((

  8. გენო says:

    სკრიპტი კი არა ვინმემ მაილზე კოდი გამომიგზავვნეთ თუ შეგიზლიათ როგორ გავაკეთო მაილი ჩემი საიტისთვის მადლობა წინასწარ

დატოვე კომენტარი:

ქართული კლავიატურა, ჩართვა/გამორთვა კლავიშით "~"