Vaka başına birden çok değeri olan bir PHP anahtarı yapmak için en iyi yolu?

11 Cevap php

Bu PHP switch deyimi ne yapardınız?

Ayrıca bu çok daha küçük versiyonları unutmayın, ben oluşturmak için gereken 1 buna eklenen çok daha fazla değerlere sahip olacaktır.

Sürüm 1:

switch ($p) { 
    case 'home': 
    case '': 
    	$current_home = 'current';
    break; 

    case 'users.online': 
    case 'users.location': 
    case 'users.featured': 
    case 'users.new': 
    case 'users.browse': 
    case 'users.search': 
    case 'users.staff': 
    	$current_users = 'current';
    break;

    case 'forum': 
    	$current_forum = 'current';
    break; 
}

Versiyon 2:

switch ($p) { 
    case 'home': 
    	$current_home = 'current';
    break; 

    case 'users.online' || 'users.location' || 'users.featured' || 'users.browse' || 'users.search' || 'users.staff': 
    	$current_users = 'current';
    break;

    case 'forum': 
    	$current_forum = 'current';
    break; 
}

UPDATE - Test Results

Ben 10.000 yineleme bazı hız testi koştu,

Time1: 0.0199389457703 // If statements
Time2: 0.0389049446106 //switch statements
Time3: 0.106977939606 // Arrays

11 Cevap

Eğer bilinmeyen bir dize var ve sen, daha fazla öğe eklemek gibi yavaş almaz tek çözüm kullanmak için other o kadar maçlar dizeleri bir demet hangi anlamaya gerek herhangi bir durum için Bir dizi, ama anahtar olarak bütün olası dizileri vardır. Yani anahtarı aşağıdaki ile değiştirilebilir:

// used for $current_home = 'current';
$group1 = array(
        'home'  => True,
        );

// used for $current_users = 'current';
$group2 = array(
        'users.online'      => True,
        'users.location'    => True,
        'users.featured'    => True,
        'users.new'         => True,
        'users.browse'      => True,
        'users.search'      => True,
        'users.staff'       => True,
        );

// used for $current_forum = 'current';
$group3 = array(
        'forum'     => True,
        );

if(isset($group1[$p]))
    $current_home = 'current';
else if(isset($group2[$p]))
    $current_users = 'current';
else if(isset($group3[$p]))
    $current_forum = 'current';
else
    user_error("\$p is invalid", E_USER_ERROR);

Bu switch() gibi temiz görünmüyor, ama derli toplu tutmak için fonksiyonları ve sınıfların küçük bir kütüphane yazmak içermez sadece fast çözümdür. Bu diziler öğeler eklemek için hala çok kolaydır.

Version 2 does not work!!

case 'users.online' || 'users.location' || ...

: tam olarak aynıdır

case True:

$p boş dize olmadıkça ve case, $p herhangi bir değeri için seçilecektir.

|| bir case deyimi içinde herhangi bir özel anlamı yok mu, sen $p bu dizeleri her karşılaştırarak değil, sadece o değil olmadığını görmek için kontrol ediyoruz False.

Bir diziye bu çok değerler koymak ve switch-case örn, okumak ve anlamak zor yapım, bir string değişken durum olarak kullanıldığında elde etmek için çalışıyoruz ne yatan semantik gizlemek gibi görünüyor, dizi sorgulamak :

$current_home = null;
$current_users = null;
$current_forum = null;

$lotsOfStrings = array('users.online', 'users.location', 'users.featured', 'users.new');

if(empty($p)) {
    $current_home = 'current';
}

if(in_array($p,$lotsOfStrings)) {
    $current_users = 'current';
}

if(0 === strcmp('forum',$p)) {
    $current_forum = 'current';
}

anyone else kodunuzu korumak için şimdiye kadar ise, neredeyse kesinlikle 2. sürümüne bir çift almak yapacağını - son derece standart dışı bulunuyor.

Ben sürüm 1 sopa ile olur. Ben gerçekten aracılığıyla düşmek için niyet göstermek için yanlarında bir açık // fall through Yorum olmalıdır kendi beyanı blok olmadan bu durum açıklamaları olsa bir okul kulüpler böylece Eğer farklı davalarını gidiyor ve unuttum falan edilip herhangi belirsizliği ortadan kaldırması.

Sürüm 1 kesinlikle, gözleri daha kolay niyetleri gibi net, ve vaka koşulları eklemek kolaydır.

Ben ikinci versiyonu hiç denemedim. Her durumda etiket, bir sabit ifade değerlendirmek zorundadır, çünkü birçok dilde, bu bile derleme değil.

Bütünlüğü uğruna, ben kırık "Version 2" mantığı çalışır ve also hız ve netlik hem de dizilerin faydalanmak, gibi pek bir switch deyimi ile değiştirilebilir olduğunu işaret edeceğiz:

// used for $current_home = 'current';
$home_group = array(
    'home'  => True,
);

// used for $current_users = 'current';
$user_group = array(
    'users.online'      => True,
    'users.location'    => True,
    'users.featured'    => True,
    'users.new'         => True,
    'users.browse'      => True,
    'users.search'      => True,
    'users.staff'       => True,
);

// used for $current_forum = 'current';
$forum_group = array(
    'forum'     => True,
);

switch (true) {
    case isset($home_group[$p]):
        $current_home = 'current';
        break;
    case isset($user_group[$p]):
        $current_users = 'current';
        break;
    case isset($forum_group[$p]):
        $current_forum = 'current';
        break;
    default:
        user_error("\$p is invalid", E_USER_ERROR);
}    

Hiçbir sürüm 2 aslında çalışmıyor ama bu tür bir yaklaşımı isterseniz (muhtemelen speediest değil, ama belki daha sezgisel) aşağıdakileri yapabilirsiniz:

switch (true) {
case ($var === 'something' || $var === 'something else'):
// do some stuff
break;
}

Diğer bazı fikirler henüz bahsedilmeyen:

switch(true){ 
  case in_array($p, array('home', '')): 
    $current_home = 'current'; break;

  case preg_match('/^users\.(online|location|featured|new|browse|search|staff)$/', $p):
    $current_users = 'current'; break;

  case 'forum' == $p:
    $current_forum = 'current'; break; 
}

Biri muhtemelen # 2 ile okunabilirliği konular hakkında şikayet edecek, ama böyle bir kod devralmasını hiçbir sorun olurdu.

Ben kesinlikle Sürüm 2 kod az hatları gerektirebilir. Sürüm 1 tercih, ama tahmin ettiğin gibi orada bir çok değere sahip bir kez okunması son derece zor olacaktır.

(Dürüst olmak gerekirse, ben bile Version 2 şimdiye kadar yasal olduğunu bilmiyordum. Ben daha önce bu şekilde yapılır hiç görmedim.)

Ben sürüm 1 gitmek için yol olduğunu düşünüyorum. Okumak ve anlamak çok kolaydır.

Ile birlikte Anahtarı variable variables size daha fazla esneklik verir:

<?php
$p = 'home'; //For testing

$p = ( strpos($p, 'users') !== false? 'users': $p);
switch ($p) { 
    default:
        $varContainer = 'current_' . $p; //Stores the variable [$current_"xyORz"] into $varContainer
        ${$varContainer} = 'current'; //Sets the VALUE of [$current_"xyORz"] to 'current'
    break;

}
//For testing
echo $current_home;
?>

To learn more, checkout variable variables and the examples I submitted to php manual:
Example 1: http://www.php.net/manual/en/language.variables.variable.php#105293
Example 2: http://www.php.net/manual/en/language.variables.variable.php#105282

Not: Bu örnek kod SMALL AND SIMPLE, sadece like it yolu. Bu test edilmiş ve çok çalışıyor oluyor