Bir işlev çağrısında isteğe bağlı argümanlar nasıl atlanır? PHP: İşlev Parametreleri ve Argümanlar

  • 03.11.2019

PHP 4/5'te, arama yaparken, belirtmek istemediklerinizi atlayarak (python'da olduğu gibi) adlandırılmış isteğe bağlı bir parametre belirtmek mümkün müdür?

function foo($a,$b="", $c="") ( // her neyse ) foo("merhaba", $c="bar"); // varsayılan olarak $b'yi istiyoruz, ancak $c'yi belirtiyoruz

Hayır, mümkün değil: üçüncü parametreyi geçmek istiyorsanız ikincisini geçmeniz gerekiyor. Ve adlandırılmış parametreler de mümkün değildir.

Bir "çözüm", yalnızca bir parametre, bir dizi kullanmak ve onu her zaman iletmek olacaktır… Ama her zaman içindeki her şeyi tanımlamayın.

işlev foo($params) ( var_dump($params); )

Ve bu şekilde çağırmak:

Foo(array("a" => "merhaba",)); foo(array("a" => "merhaba", "c" => "glop",)); foo(array("a" => "merhaba", "test" => "başka bir tane",));

Size bu çıktıyı alacak:

Dizi "a" => dize "merhaba" (uzunluk=5) dizi "a" => dize "merhaba" (uzunluk=5) "c" => dize "glop" (uzunluk=4) dizi "a" => string "merhaba" (uzunluk=5) "test" => string "başka bir tane" (uzunluk=11)

Ancak bu çözümü gerçekten sevmiyorum:

  • phpdoc'u kaybedeceksin
  • IDE'niz artık herhangi bir ipucu sağlayamayacak… Bu kötü

Bu yüzden bununla sadece çok özel durumlarda giderdim - örneğin birçok isteğe bağlı parametreye sahip işlevler için…

Hayır, PHP argümanları ada göre iletemez.

Çok fazla argüman alan bir fonksiyonunuz varsa ve hepsinin varsayılan değerleri varsa, bunun yerine fonksiyonun bir dizi argümanı kabul etmesini sağlayabilirsiniz:

İşlev testi (dizi $args) ( $defaults = array("a" => "", "b" => "", "c" => ""); $args = array_merge($varsayılanlar, array_intersect_key($args) , $varsayılanlar)); list($a, $b, $c) = dizi_değerleri($args); // list()'e bir alternatif: özü($args); // artık $a, $b kullanabilirsiniz , $c )

Bunu bir şekilde yapmanın tek yolu, dizileri adlandırılmış anahtarlarla kullanmaktır.

PHP ile önemli olan argümanların sırasıdır. Belirli bir argümanı yerinde belirtemezsiniz, ancak bunun yerine, işlevinizdeki değerin NULL değerine sahip olmasına aldırış etmediğiniz sürece, bir NULL ileterek argümanları atlayabilirsiniz.

Foo("merhaba", NULL, "bar");

itibariyle PHP 5.4 steno dizi sözdiziminiz var (kullanışlı "dizi" içeren dizileri belirtmek için gerekli değil ve bunun yerine "" kullanın).

Yapabilirsiniz mimik birçok yönden adlandırılmış parametreler, iyi ve basit bir yol olabilir:

Bar("bir", ["a1" => "iki", "bar" => "üç", "foo" => "dört"]); // çıktı: iki üç dörtlü fonksiyon çubuğu ($a1, $kwargs = ["bar" => null, "foo" => null]) ( özüt($kwargs); echo $a1; echo $bar; echo $foo; )

Tam olarak güzel değil, ama bazılarına göre hile yapıyor.

Sınıf NamedArguments ( static function init($args) ( $assoc = reset($args); if (is_array($assoc)) ( $diff = array_diff(array_keys($assoc), array_keys($args)); if (boş) ($diff)) return $assoc;trigger_error("Geçersiz parametreler: ".join(",$diff), E_USER_ERROR); ) return array(); ) ) class Test ( public static function foobar($gerekli, $opsiyonel1 =) "", $opsiyonel2 = "") ( extract(NamedArguments::init(get_defined_vars())); printf("gerekli: %s, isteğe bağlı1: %s, isteğe bağlı2: %s\n", $gerekli, $ isteğe bağlı1, $opsiyonel2); ) ) Test::foobar("gerekli", "isteğe bağlı1", "isteğe bağlı2"); Test::foobar(array("gerekli" => "gerekli", "isteğe bağlı1" => "isteğe bağlı1", "isteğe bağlı2" => "isteğe bağlı2"));

Bir dizi yerine bir nesne ileterek phpdoc'u ve varsayılanları ayarlama yeteneğini koruyabilirsiniz, örn.

FooOptions Sınıfı ( $opt1 = "x"; $opt2 = "y"; /* vb */ );

Bu ayrıca, aşağıdakileri yapmak istiyorsanız, işlev çağrınızda katı tip denetimi yapmanıza da olanak tanır:

foo işlevi (FooOptions $opts) ( ... )

Tabii ki, bunun için FooOptions nesnesini ayarlamak için ekstra ayrıntıyla ödeme yapabilirsiniz. Ne yazık ki, tamamen ücretsiz bir yolculuk yok.

Normalde yapamazsınız, ancak adlandırılmış argümanları bir PHP işlevine iletmenin birçok yolu olduğunu düşünüyorum. Şahsen ben dizileri kullanarak tanımı aktarıyorum ve sadece geçmem gerekeni çağırıyorum:

Sınıf Testi( public $a = false; private $b = false; public $c = false; public $d = false; public $e = false; public function _factory()( $args = func_get_args(); $args = $ args; $bu->a = array_key_exists("a",$args) ? $args["a"] : 0; $bu->b = array_key_exists("b",$args) ? $args["b" ] : 0; $bu->c = array_key_exists("c",$args) ? $args["c"] : 0; $bu->d = array_key_exists("d",$args) ? $args[" d"] : 0; $this->e = array_key_exists("e",$args) ? $args["e"] : 0; ) public function show()( var_dump($this); ) ) $test = yeni Test(); $args["c"]=999; $test->_factory($args); $deneme->göster();

10 argüman iletmem gerekiyorsa ve bunlardan 3'ü gerçekten ihtiyacım olan verilerse, işleve şunun gibi bir şey iletmek için AKILLI DEĞİLDİR

İşlevimi döndür(yanlış,yanlış,10,yanlış,yanlış,"tarih",yanlış,yanlış,yanlış,"azalan");

Verdiğim yaklaşımla, 10 argümandan herhangi birini bir diziye kurabilirsiniz:

$dizi["say"]=10; $dizi["type"]="tarih"; $dizi["sipariş"]="azalan"; işlevimi döndür($dizi);

Blogumda bu süreci daha ayrıntılı olarak açıklayan bir yazım var.

İşte kullandığım şey. Bir işlev tanımı, isteğe bağlı adlandırılmış bağımsız değişkenlerin bir isteğe bağlı dizi bağımsız değişkeni alacağını belirtir:

function func($arg, $options = Array()) ( $defaults = Array("foo" => 1.0, "bar" => FALSE); $options = array_merge($varsayılan, $options); // Normal işlev Buradaki gövde. Adlandırılmış parametre değerlerini getirmek için $options["foo"] ve // ​​$options["bar"] kullanın. ... )

Normalde herhangi bir adlandırılmış bağımsız değişken olmadan arayabilirsiniz:

İşlev ("xyzzy")

İsteğe bağlı bir adlandırılmış bağımsız değişken belirtmek için onu isteğe bağlı diziye iletin:

Func("xyzzy", Array("foo" => 5.7))

Tam olarak değil. Bunun için kullanabileceğiniz birkaç alternatif var.

Test(null,null,"merhaba")

Veya bir diziyi iletin:

Test(array("c" => "merhaba"));

O halde fonksiyon şöyle olabilir:

İşlev testi($dizi) ( $c = isset($dizi[c]) ? $dizi[c] : ""; )

Veya arasına bir işlev ekleyin, ancak bunu önermem:

İşlev ctest($c) ( test("","",$c); )

İşlev testini deneyin ($a="",$b="",&$c="")()

$c'nin önüne & koyarak

Öyle düşünmüyorum…
Örneğin, 3 parametresi olan substr işlevini çağırmanız gerekiyorsa ve Ayarlamak$ uzunluk olmadan$start'ı ayarlayın, bunu yapmak zorunda kalacaksınız.

Altdizi($str,0,10);

bunu geçersiz kılmanın güzel bir yolu her zaman kullanmaktır diziler parametreler için

basit cevap. Hayır, yapamazsın.
Bir nesneyi/diziyi geçerek veya başka Bağımlılık ekleme kalıplarını kullanarak onu aşmayı deneyebilirsiniz.

Ayrıca, is_null() kullanarak varlıklarını test etmek daha kesin olduğundan, boş dizeler yerine boş dizeler kullanmayı deneyin.

İşlev testi ($a=null,$b=null,$c=null)( if (is_null($a) ( //$a hakkında bir şey yap) if (is_null($b) ( //$b hakkında bir şey yap) ) if (is_null($c) ( //$c hakkında bir şeyler yapın) )

Test(null,null,"Merhaba");

Çok kısaca, bazen evet, yansıma ve yazılan değişkenleri kullanarak. Ancak, muhtemelen peşinde olduğunuz şeyin bu olmadığını düşünüyorum.

Sorununuza daha iyi bir çözüm, muhtemelen 3 argümanı iletmenizdir, çünkü işlevler, işlevinizdeki eksik olanı kendiniz halleder.

Python yolu ile yapamazsınız. Yine de, ilişkisel bir diziyi geçebilir ve dizi girişlerini adlarına göre kullanabilirsiniz:

Fonksiyon testi ($args=array("a"=>"","b"=>"","c"=>"")) ( // bir şeyler yap ) test(array("c"=>"Merhaba) "));

Bu, yazmayı azaltmaz, ancak en azından daha açıklayıcıdır, argümanların adlarının çağrıda görünür ve okunabilir olması.

İşte bir çalışma:

fonksiyon set_param_defaults($params) ( foreach($params["default_values"] as $arg_name => $arg_value) ( ​​if (!isset($params[$arg_name])) ( $params[$arg_name] = $arg_value ; ) ) $params; ) function foo($z, $x = null, $y = null) ( $varsayılan_değerler = ["x" => "x için varsayılan değer", "y" => "varsayılan değer" y için değer" ]; $params = set_param_defaults(get_defined_vars()); "$z\n" yazdır; $params["x"] yazdır . "\n"; $params["y"] yazdır. "\n "; ) foo ("z değerini ayarla", null, "y değerini ayarla"); "\n" yazdır; foo("x değerini ayarla", "x değerini ayarla");

ALTERNATİF OLARAK:
Şahsen ben bu yöntemle giderdim.

foo($z, $x_y) ( $x_y += ["x" => "x için varsayılan değer", "y" => "y için varsayılan değer"]; print "$z\n"; print $ x_y["x"] . "\n"; print $x_y["y"] . "\n"; ) foo("z değerini ayarla", ["y" => "y değerini ayarla"]); "\n" yazdır; foo("x değerini ayarla", ["x" => "x değerini ayarla"]);

Her iki örnek için çıktılar.

  • z değerini ayarla
  • x için varsayılan değer
  • y değerini ayarla
  • z değerini ayarla
  • x değerini ayarla
  • y için varsayılan değer

Sadece Drupal'ın kullandığı ilişkisel dizi modelini kullanın. İsteğe bağlı varsayılan argümanlar için, argümanın ilişkisel bir dizi olduğu bir $options kabul edin. Ardından dizideki eksik anahtarları ayarlamak için dizi + operatörünü kullanın.

foo ($a_required_parameter, $options = dizi()) ( $seçenekler += dizi("b" => "", "c" => "",); // her neyse ) foo("a", dizi( "c" => "c'nin değeri")); // c belirtilirken b'yi geçmeye gerek yok.

Parametreler, işlev tanımında parantez içinde belirtilir ve yerel değişkenleridir, yani. yalnızca gövdesinde görünürler, birkaç parametre varsa, virgülle ayrılmış olarak belirtilirler. Çağrıldığında, bir işlev, parametrelerin başlatıldığı argümanları alabilir.

Parametrelerin ne olduğunu düşündük, şimdi hangi değerlerle başlatıldığını öğreneceğiz. Parametrelere atanacak değerlere argümanlar denir - bu, örneğin bir dize veya tamsayı değişmezi, bir değişken veya değişkenlerden ve operatörlerden oluşan, ancak PHP tarafından değerlendirilebilen daha karmaşık bir ifade olabilir. parametrenin başlatılacağı değeri elde etmek için yorumlayıcı. Basitçe söylemek gerekirse, bir argüman bir fonksiyona iletilen bir değerdir:

Argümanları Geçmek

PHP, işlev argümanlarını iletmenin iki yolunu destekler. İlki, argümanları değere göre iletir (varsayılan olarak çalışır), ikincisi argümanları referansa göre iletir. PHP ayrıca varsayılan değerleri de destekler. Şimdi her üç seçeneğe daha ayrıntılı olarak bakalım.

Varsayılan olarak, bağımsız değişkenler bir işleve değere göre iletilir (bu, işlev içindeki bir parametrenin değerini değiştirirseniz, iletilen değerin işlevin dışında aynı kalacağı anlamına gelir):

$color color"; // Değişkenin değeri değişti mi?>

Bir işlevin dışında geçirilen argümanları değiştirmesine izin vermek istiyorsanız, bunları referans olarak iletmelisiniz. Bir argümanın referans olarak iletilmesi için, fonksiyon tanımında parametre adından önce & (ve işareti) işaretini belirtmelisiniz:

Fonksiyonlar, varsayılan argüman değerlerini tanımlayabilir. Varsayılan bir değer ayarlamak için fonksiyon tanımında tek yapmanız gereken parametreyi istenen değere ayarlamaktır:

\n"; ) echo tea(); // varsayılan değeri yazdırır echo tea("siyah"); ?>

Not: Varsayılan bağımsız değişken değerlerine sahip tüm parametreler, varsayılan değerleri olmayan bağımsız değişkenlerin sağında olmalıdır, aksi takdirde kodunuz beklendiği gibi çalışmayabilir:

İşlev dönüş değeri

Bir fonksiyon sona erdiğinde, onu çağıran programa bir değer (fonksiyonun sonucu) döndürebilir. Fonksiyonların içindeki return ifadesi, fonksiyon tarafından döndürülen değeri belirlemek için kullanılır. Dönüş değeri herhangi bir tür olabilir. Aşağıdaki sözdizimine sahiptir:

dönüş ifadesi;

Return ifadesi, bir işlevde herhangi bir yere yerleştirilebilir. Kontrol ona ulaştığında, işlev (belirtilmişse) bir değer döndürür ve yürütmesini sona erdirir. Dönüş ifadesi belirtilmezse veya dönüş değeri belirtilmezse, işlev NULL değerini döndürür. Dönüş değerini kullanmak için, fonksiyon yürütmenin sonucu bir değişkene atanabilir, örneğin:

"; // => 16. function foo($num) ( if($num === 10) return "$sayı 10'a eşittir"; aksi takdirde "$sayı 10'a eşit değil"; echo "merhaba" ; // bu kod satırı asla çalıştırılmayacaktır ) echo foo(6); ?>

Mesajınız doğru.

Ne yazık ki, parametre listesinin en sonunda isteğe bağlı bir parametre kullanmanız gerekiyorsa, son parametreye kadar her şeyi belirtmeniz gerekir. Genel olarak, karıştırmak ve eşleştirmek istiyorsanız, onlara varsayılan "" veya null değerlerini verirsiniz ve varsayılanlarsa bunları bir işlev içinde kullanmayın.

Bir argümanı "atlamanın", false veya null varsayılan değerini belirtmekten başka bir yolu yoktur.

PHP sözdizimsel şekerden yoksun olduğundan, genellikle şöyle bir şey görürsünüz:

Checkbox_field(array("isim" => "bir isim", ....));

Bu, yorumlarda açıkça söylendiği gibi, adlandırılmış argümanları taklit etmek için dizileri kullanır.

Bu maksimum esneklik sağlar, ancak bazı durumlarda gerekli olmayabilir. En azından, çoğu durumda beklenmediğini düşündüğünüz her şeyi argüman listesinin sonuna taşıyabilirsiniz.

Hayır, bu şekilde argümanları atlamak mümkün değil. Geçen argümanları atlayabilirsiniz sadece bunda parametre listesinin sonundaysa.

Bunun için resmi bir teklif vardı: https://wiki.php.net/rfc/skipparams reddedildi. Öneri sayfası, bu konuyla ilgili diğer SO sorularına bağlantı verir.

Ancak, doğru sözdizimi için ve atlamak istediğim bağımsız değişkenler için NULL belirtmek için isteğe bağlı bağımsız değişkenleri atlama yeteneği ile ilgili hiçbir şey değişmedi, bunu nasıl yapacağım:

Define("DEFAULT_DATA_LIMIT", "50"); define("DEFAULT_DATA_PAGE", "1"); /** * getData * bir veri sayfası al * * Parametreler: * isim - (gerekli) elde edilecek verinin adı * limit - (isteğe bağlı) varsayılan limiti almak için NULL gönder: 50 * sayfa - (isteğe bağlı) NULL gönder varsayılan sayfayı almak için: 1 * Döndürür: * dizi olarak bir veri sayfası */ function getData($name, $limit = NULL, $page = NULL) ( $limit = ($limit==NULL) ? DEFAULT_DATA_LIMIT: $sınır; $sayfa = ($sayfa==NULL) ? DEFAULT_DATA_PAGE: $sayfa; ... )

Bunu şöyle adlandırabilirsiniz: getData("bir isim",NULL,"23"); ve gelecekte işlevi çağıran hiç kimse, her seferinde varsayılan değerleri veya onlar için bildirilen sabiti hatırlamak zorunda kalmaz.

Basit cevap: Değil. Fakat argümanları yeniden düzenlerken bunu neden atlayasınız ki?

seninki -" Varsayılan işlev bağımsız değişkenlerinin yanlış kullanımı' ve beklediğiniz gibi çalışmayacak.

PHP belgelerinden yan not:

Varsayılan bağımsız değişkenleri kullanırken, herhangi bir varsayılan değer, varsayılan olmayan herhangi bir bağımsız değişkenin sağ tarafında olmalıdır; aksi takdirde işler beklendiği gibi çalışmayacaktır.

Aşağıdakileri göz önünde bulundur:

function getData($name, $limit = "50", $page = "1") (dönüş "Seç * kitaplardan NEREDE ad = $ad VE sayfa = $sayfa sınırı $limit"; ) echo getData("bir ad" , "", "23"); // beklendiği gibi çalışmayacak

Çıktı olacaktır:

"Seçin * kitaplardan NEREDE isim = bir isim VE sayfa = 23 limit"

Varsayılan işlev argümanlarının doğru kullanımı aşağıdaki gibi olmalıdır:

function getData($name, $page = "1", $limit = "50") (döndür "Seç * kitaplardan NEREDE ad = $ad VE sayfa = $sayfa sınırı $limit"; ) echo getData("bir ad" , "23"); // beklendiği gibi çalışır

Çıktı olacaktır:

"Seçin * kitaplardan NEREDE isim = bir isim VE sayfa = 23 limit 50"

Varsayılan olarak, standart olmayan değerlerden sonra, tanımlanmamış/belirtilmemişse, o değişken için varsayılan değeri her zaman yeniden yapılandırır. İşte referans için bir bağlantı ve bu örneklerin nereden geldiği.

Düzenleme: Bunu, diğerleri gibi null olarak ayarlamak işe yarayabilir ve başka bir alternatiftir, ancak istediğiniz gibi olmayabilir. Tanımlanmamışsa her zaman varsayılan değeri null olarak ayarlar.

Yukarıda belirtildiği gibi, seçenekleri atlayamazsınız. Bu cevabı, bir yoruma sığmayacak kadar büyük bir ekleme sağlamak için yazdım.

@Frank Nocke, işlevin varsayılan parametreleriyle çağrılmasını önerir, örneğin

a($b=0, $c=NULL, $d="")( //...

kullanmalısın

$var = a(0, NULL, "ddd");

bu, ilk iki parametreyi ($b ve $c) atlamakla aynı işlevi görecektir.

Bunlardan hangisinin varsayılan olduğu net değil (varsayılanı belirtmek için 0'a ayarlandı mı yoksa önemli mi?).

Varsayılan değerler sorununun, varsayılan değerlerin işlev (veya yöntem) yazarı tarafından değiştirilebileceği harici (veya yerleşik) bir işlevle ilgili olması tehlikesi de vardır. Yani programda aramanızı değiştirmezseniz, istemeden davranışını değiştirebilirsiniz.

Bazı geçici çözümler, DEFAULT_A_B gibi "işlev parametresi B parametresi A'nın varsayılan değeri" olacak ve bunun gibi "atla" olacak bazı genel sabitleri tanımlamak olabilir:

$var = a(DEFAULT_A_B, DEFAULT_A_C, "ddd");

Sınıflar için, küresel kapsamın bir parçası oldukları için sınıf sabitlerini tanımlamanız daha kolay ve zariftir, ör.

Sınıf MyObjectClass ( const DEFAULT_A_B = 0; function a($b = self::DEFAULT_A_B)( // yöntem gövdesi ) ) $obj = new MyObjectClass(); $var = $nesne->a(MyObjectClass::DEFAULT_A_B); //vb.

Bu varsayılan sabitin kod boyunca tam olarak bir kez tanımlandığını unutmayın (yöntem bildiriminde bile değer yoktur), bu nedenle beklenmeyen değişiklikler olması durumunda işleve/yönteme her zaman doğru varsayılan değeri sağlarsınız.

Bu çözümün netliği elbette okuyucuya hiçbir şey söylemeyen ham varsayılan değerler (NULL , 0 vb. gibi) sağlamaktan daha iyidir.

($var = a(,"ddd"); gibi çağırmanın en iyi seçenek olacağına katılıyorum)

Atlanan herhangi bir parametre için (yapmalısınız), güvenli tarafta olmak için varsayılan parametre ile gidin.

(Varsayılan parametrenin "" veya benzeri olduğu veya tam tersi olduğu yerde null olarak ayarlamak başınızı belaya sokar...)

Argümanları atlayamazsınız, ancak dizi parametrelerini kullanabilirsiniz ve yalnızca bir parametre dizisi olan bir parametre tanımlamanız gerekir.

function myfunction($dizi_param) ( echo $dizi_param["ad"]; echo $dizi_param["yaş"]; ................. )

Ve istediğiniz kadar parametre ekleyebilirsiniz, bunları tanımlamanız gerekmez. Bir işlevi çağırdığınızda, parametrelerinizi şu şekilde ayarlarsınız:

Fonksiyonum(array("isim" => "Bob", "yaş" => "18", .........));

Pekala, herkesin söylediği gibi, istediğiniz şey PHP'de fonksiyonlara bazı kod satırları eklemeden mümkün olmayacak.

Ancak, işlevlerinizi almak için bu kod parçasını bir işlevin en üstüne yerleştirebilirsiniz:

Foreach((new ReflectionFunction(debug_backtrace()["function"]))->getParameters() as $param) ( if(empty($($param->getName())) && $param->isOptional()) $($param->getName()) = $param->getDefaultValue(); )

Temel olarak debug_backtrace() ile bu kodun yerleştirildiği işlevin adını alıyorum, böylece yeni bir ReflectionFunction nesnesi oluşturabilir ve tüm işlev argümanlarını döngüye sokabilirim.

Döngüde, işlev argümanının boş () olup olmadığını ve argümanın "isteğe bağlı" olup olmadığını kontrol ediyorum (varsayılan bir değeri olduğu anlamına gelir). Eğer öyleyse, argümana sadece varsayılan bir değer atarım.

gösteri

Sınırı null olarak ayarla

fonksiyon getData($isim, $limit = null, $sayfa = "1") ( ... )

ve bu işlevi çağırmak

GetData("bir isim", null, "23");

bir sınır belirlemek istiyorsanız argüman olarak iletebilirsiniz

GetData("bir isim", 50, "23");

Daha önce de belirtildiği gibi, hiçbir şey değişmedi. Yine de dikkatli olun, çok fazla parametre (özellikle isteğe bağlı olanlar) kod kokusunun güçlü bir göstergesidir.

Belki de işleviniz çok fazladır:

// önce bağlamı oluştur $dataFetcher->setPage(1); // $dataFetcher->setPageSize(50); // burada kullanılmaz // sonra işi yap $dataFetcher->getData("bir isim");

Bazı seçenekler mantıksal olarak gruplandırılabilir:

$sayfalandırma = new Sayfalandırma(1 /*, 50*/); getData("bir isim", $sayfalama); // Java kodlayıcıları muhtemelen bu forma aşina olacaktır: getData("bir ad", new Pagination(1));

İkinci durumda, her zaman bir geçici parametre nesnesi girebilirsiniz:

$param = new GetDataParameter(); $param->setPage(1); // $param->setPageSize(50); // burada kullanılmaz getData($param);

(bu, daha az resmi yöntemin yalnızca yüceltilmiş bir versiyonudur parametre dizisi)

Bazen parametre oluşturma nedeni isteğe bağlıdır. Bu örnekte, $page gerçekten isteğe bağlı olmak anlamına mı geliyor? Birden çok karakteri kaydetmek gerçekten önemli mi?

// şüpheli // ilk bakışta "getData()"ya parametresiz bir çağrının // veri fonksiyonunun yalnızca bir sayfasını döndürdüğü açık değildir getData($page = 1); // bu daha mantıklı function log($message, $timestamp = null /* varsayılan olarak geçerli zaman */);

Bu snippet:

function getData($name, $options)( $varsayılan = dizi("limit" => 50, "sayfa" => 2,); $args = array_merge($varsayılan, $options); print_r($arg); ) getData("foo",dizi()); getData("foo", dizi("limit" => 2)); getData("foo", array("limit" => 10, "sayfa" => 10));

Dizi ( => 50 [sayfa] => 2) dizi ( => 2 [sayfa] => 2) dizi ( => 10 [sayfa] => 10)

Yapacağım şey buydu:

Umarım bu birine yardımcı olur

Dene.

fonksiyon getData($isim, $limit = NULL, $sayfa = "1") ( if (!$limit)( $limit = 50; ) ) getData("bir isim", "", "23");

Bir işlev çağrısında ortadaki parametreyi atlayamazsınız. Ancak bunun üzerinde çalışabilirsiniz:

Function_call("1", "2", "3"); // Parametre ile geç. function_call("1", boş, "3"); // Parametresiz geç.

function function_call($a, $b="50", $c)( if(isset($b))( echo $b; ) else( echo "50"; ) )

@IbrahimLawal'ın belirttiği gibi. Bunları boş değerlere ayarlamak en iyisidir. Yalnızca ayarlanmış varsayılanlarınızı kullandığınız değerin boş olup olmadığını kontrol edin.

Bu yardımcı olur umarım.

GetData("bir isim");

sadece onları geçmeyin ve varsayılan değer alınacaktır

>

php işlevleri

>

php betikleri

func_get_arg

func_get_arg-- Argüman listesinden bir öğe döndürür

Tanım

karışık func_get_arg (int arg_num)

Kullanıcı tanımlı işlevin bağımsız değişken listesinden arg_num -th bağımsız değişkenini döndürür. İşlev argümanlarının numaralandırılması sıfırdan başlar. func_get_arg() fonksiyon tanımının dışında çağrıldığında bir uyarı oluşturur.

arg_num, iletilen argüman sayısından büyükse, bir uyarı oluşturulur ve func_get_arg() geri dönücek YANLIŞ .

işlev bilgisi()
{
$sayılar = func_num_args();
Eko"Argüman sayısı: $numargs
\n" ;
eğer($sayılar >= 2) (
Eko"İkinci argüman: " . func_get_arg (1) . "
\n" ;
}
}

foo (1 , 2 , 3);
?>

func_get_arg() ile birlikte kullanılabilir func_num_args() ve func_get_args() değişken sayıda argüman içeren işlevler oluşturmak için.

Kullanıcı Tarafından Katkıda Bulunan Notlar

piskopos
11-Aralık 2004 08:58

"Erteleme" operatörü hakkında için ssc dot wisc dot edu'da dvogel, zehrini seç:

// üçlü operatörleri kullanma
işlev seçimi ($a , $b ) ( dönüş ( isset($a) ? $a: $b); )
$a = (seç ($b , $c ) ? seç ($c , $d ) : null);
?>
// varargs işlevini kullanarak
işlev seçimi ($a ) (
$a rg c= func_num_args();
için($i = 0 ; $i< $a rg c; $i++) (
$a rg = func_get_arg($i);
eğer (! is_null ($a rg)) {
dönüş $a rg ;
}
}

null döndür;
}

$a = seç ($b , $c , $d );
?>


mw atto lanfear dotto com
08-Aralık 2004 01:56

func_get_arg() içinde bir işlev argümanı olarak kullanılmasına izin verilmiş gibi görünmüyor sınıf PHP 5.0.2'deki kurucular (wonk-ay!!!):

sınıf ABC
{
işlev __construct()
{
her biri için(func_get_args() $name => $değer olarak)
{
Eko <<

$isim : $değer


EOT;
}
}
}

sınıf DEF uzanır ABC
{
işlev __construct()
{
ebeveyn::__construct( func_get_arg (0),
func_get_arg (1),
func_get_arg (2));
}
}

$def = yeni DEF(123123, "asdfasdf", "blahblahblah");

Yukarıdaki komut dosyası şunları üretir:

ölümcül hata: func_get_arg(): 23. satırda c:\Inetpub\wwwroot\phpwasrc\chapter10\xxx'te bir işlev parametresi olarak kullanılamaz

Ancak bunları normal fonksiyonlara parametre olarak geçirirken herhangi bir sorun yoktur.
ssc dot wisc dot edu'da dvogel
22-Ekim-2004 01:54

Bu ifadeyi kullanabilmek için her zaman bir erteleme veya kademeli operatör istiyorum:

$a = $b ## $c ## $d ;

Ve atama operatörünün sağındaki her şey, boş olmayan en soldaki değere göre değerlendirilir. Esasen bunun daraltılmış bir versiyonudur:

eğer($b ) (
$a =$b ;
} başka {
eğer($c ) (
$a =$c ;
} başka {
eğer($g ) (
$a = $d ;
} başka {
$a = boş;
}
}
}

Bunun yerine, değişken sayıda argüman alan ve null olmayan ilkini döndüren bir işlev yapmaya çalışıyorum. Bunu bazı büyük dizilerde kullanmak istiyorum, bu yüzden geçmek istiyorum Bunlar referans olarak. Ancak, PHP'nin daha yeni sürümlerinde çağrı zamanı referans geçişi devre dışıdır (ve öyle olmalıdır). =

Aklıma gelen tek çözüm, değişkenlerin referansına göre ayarlanmasıdır. dizi ilk. Örneğin.

$a = dizi (...);
$b = 0;
$c =
first_not_null($a , $b );

Daha iyi bir çözüm bilen var mı?
harald at triptop dot org
15-Eylül 2004 02:09

func_get_arg kullanışlı, eğer argümanların tam sırasını biliyorsunuz veya eğer sıra önemli değil. bu işlevi kullanıyorum (veya func_get_args) için kendi oluşturmak için örnek sprintf sarmalayıcılar.

eğer bir işleve değişken sayıda argüman iletmek istiyorsanız, bence daha iyi, onu bir anahtar/değer olarak göndermek diziÖrneğin.:

işlev çağrısı( dizi("param1" => "..." ,...));
?>

Ve "ayıklayın" dizi all.php?act=funct&argument= içinde tip kontrolü gibi numaralar yapmanıza gerek yok için parametre tanıma, bu durumda.
04-Haziran 2004 05:16

aslında bir ihtiyaç olduğunu düşünüyorum için bu tür "kesinlikle her şeyi yap" işlevleri. Onları çoğunlukla araç olarak kullanıyorum için Hızlı prototipleme.
Ve bir fonksiyona birkaç karakter dizisini iletebileceğiniz bir metot vardır: egzama ();
Başka bir kullanım için bu tür işlevler küçük kod parçacıkları oluşturmaktır için oradaki diğer insanlar. Artık işlevi düzenlemek zorunda kalmayacaklar eğer parametre kullanmazlar. all.php?act=funct&argument= çağrılırken sadece adını vermiyorlar.
Bu, kullanımları çok sağlam olan çok yönlü işlevlerle sonuçlanır. Normalde sadece küçük bir kod parçacığına sahip olursunuz (örneğin, ip engelleme parçacıkları). Bu tür programlama sayesinde tüm işlevlere sahip olursunuz.
26-Mayıs 2004 08:29

Aynı türden en az iki parametre belirtmeniz gerekmedikçe çok akıllıca - hangisi hangisi? Açıkçası, bazı varsayılanlara karar verebilirsiniz, ancak sonra her şey çirkinleşir. Ne eğer SADECE bir dizeye ihtiyacınız var eğer bir boole de sağlandı mı? Tip denetimi, işlevinizin ana odağı haline gelir, kahretsin. İçin temiz kod uğruna, işlevlerinize temiz bir arayüz belirtmeli ve argüman olarak neyin ve nereye iletileceğine karar vermelisiniz. Evet, her zaman bir do_absolutely_everything() işlevini kodlayabilirsiniz, ancak bunun bir anlamı var mı?
anders at ingemann dot fakestuff dot de
30-Nis-2004 03:18

Gayet güzel bir şey için kullanıcı tanımlanmış işlevler yalnızca gerekli parametreleri göndermek içindir. Eğer yapmanız gereken üç isteğe bağlı parametreye sahip bir işlevi çağırırsınız. tanımlamak ilk ikisi (hatta eğer gibi kalmalılar tanımlanmış işlevde standart), işleve üçüncü önemli parametrenin ne olduğunu söylemeden önce. Bunun yerine, hangi değişkene atanması gerektiğini, gönderilen parametrenin modeline veya türüne göre de öğrenebilirsiniz.
bunun gibi:

işlev ne olursa olsun()
{
için($i = 0 ; $i< func_num_args (); $i ++)
{
eğer (is_bool (func_get_arg($i))) $log_ip = func_get_arg($i);
eğer (is_int (func_get_arg($i))) $sınır = func_get_arg($i);
eğer (is_string (func_get_arg($i))) $isim = func_get_arg($i);
}
}
?>

Artık istediğiniz parametre ile fonksiyonu çağırabilirsiniz.
Örneğin.:

şöyle dava$ limiti olur tanımlanmış 3600 ile.

Önemli değil eğer bunu yap:


veya bu:

veya bu:

Ayrıca kullanabilirsiniz egzama(). Bu sayede birden fazla parametreyi string olarak kullanabilirsiniz.
hmm muhtemelen egzama() en iyi çözümdür...
boşver.
sadece kontrol et ;-)
Mightye (at) Mightye (nokta) kuruluş
12-Mart 2004 08:45

func_get_arg() bir * döndürür kopyalamak* argümanın, bildiğim kadarıyla değişken sayıda argümana referans almanın bir yolu yok.

Oyunumda, bir modüldeki işlevlere değişken sayıda argüman iletebilmek ve bunları referans olarak iletebilmek istediğim bir modül sistemim var. eğer modül soruyor için referans olarak, ancak isteğe bağlı parametreleri referans olarak kabul edemezsiniz veya değişken sayıda argüman üzerindeki referansı alamazsınız. Görünüşe göre modüllerimin işlevlerine referans yoluyla parametreleri kabul etme yeteneği dışında olması gerekecek.
classaxe dot com'da martin
07-Haziran 2002 09:55

Bu işlev zarif olmakla birlikte, elbette uyarıları kapatmadığınız sürece, değişkenlerin ayarlanmadığı durumlarda uyarı mesajları oluşturma sorununu ortadan kaldırmaz:
error_reporting(E_HATA);

Cevap için gerekli uyarıları görmek isteyenler?
Şöyle adlandırın:
@allSet($w , $x , $y , $z )

Bir web sitesinde değişiklik yapmaya gelince, ziyaretçilerin yeni özellikler ve işlevler hakkında ne düşündüklerini duymak her zaman iyidir. Çok uzun bir süre boyunca, geliştiriciler, kullanıcı geri bildirimlerinin işe yarayacağı umuduyla yalnızca iletişim formunu kullanmakla sınırlıydı, bu da ne yazık ki her zaman sonuç getirmedi.

Bugün yaklaşımı değiştireceğiz - birçok tanınmış siteye başarı getiren sosyal ilkeyi kullanacağız ve ayrıca sitede gelecekteki değişiklikler için tavsiye bırakmaktan ve başkalarının önerilerine oy vermekten mutlu olan ziyaretçiler arasında çok popüler olacağız. .

XHTML

Yeni HTML5 belge türünü kullanma, bir bölüm tanımlama kafa, etiket ekle Başlık, ana stil sayfası - stiller.css .

demo.php

Gelecek için öneriler (PHP, jQuery ve MySQL kullanarak) | İnternet sitesi



Sonra etikete git gövde ve div #sayfa, hangi ana kapsayıcıdır. Bir başlık, tüm tekliflerin sırasız bir listesini (PHP tarafından oluşturulan) ve bir başvuru formu içerir.

Son olarak, Google AJAX Kitaplığı CDN'sinden jQuery kitaplığını ve komut dosyamızı dahil ediyoruz. script.js, öğreticinin sonraki bölümünde ayrıntılı olarak açıklanacaktır.


Veritabanı tablolarının yapısı

Uygulamamız, verileri depolamak için iki MySQL tablosu kullanır. öneriler ve Öneriler_oylar. İlk tablo, teklifin metnini ve teklifin aldığı derecelendirme ve oy sayısı gibi verileri içerir. İkinci tablo, seçmenin IP adresi ile kayıtları tutar ve aynı IP'den bir öğeye günde bir defadan fazla oy verilmesini engeller.


Tablo yapısı öneriler

Veri seçimi sorgusunu hızlandırmak için indeks alan tarafından belirlenir. değerlendirme. Bu yaklaşım, teklifler popülerliğe göre sıralandığında kullanışlıdır.

Masa Öneriler_oylarüç alandan oluşan bir ana anahtara sahiptir - öneri_kimliği, IP, ve tarih. Birincil anahtar yinelenen satırlara izin vermediğinden, kullanıcının yalnızca değişkenin değerini kontrol ederek günde yalnızca bir kez oy verebileceğinden emin olabiliriz. etkilenen_rows ekleme işleminden sonra.


Tablo yapısı Öneriler_Oylar

PHP

Bir cümle yan tümcesi oluşturup AJAX eylemleri gerçekleştirmeden önce PHP sınıfına bakmamız gerekir. öneri. Kodumuza işlevsellik sağlamak için iki PHP sihirli yöntemi (kurucu dışında) kullanır. Bir sayfa oluşturulduğunda, PHP bir MySQL veritabanı sorgusu yürütür ve tablodaki her satır için bu sınıfın bir nesnesini oluşturur. Her satırdaki sütunlar, nesne özellikleri olarak eklenir.

öneri.sınıf.php

class Öneri ( private $veri = dizi(); public function __construct($dizi = dizi()) ( if(!empty($dizi))( // $dizi dizisi yalnızca // elle bir nesne oluşturduğumuzda iletilir ajax.php'de verilen sınıfın $this->data = $arr; ) ) public function __get($property)( // Var olmayan bir özelliğe erişirsek // bu sihirli yöntem çağrılır. if(array_key_exists) ($property, $this->data))( return $this->data[$property]; ) return NULL; ) public function __toString() ( // Bir nesne bir dizgeye dönüştürülürken // bu sihirli yöntem çağrılır : dönüş "
  • kimlik."">
    oy kullandınız mı? "etkin değil" : "etkin")."">
    ".$bu->öneri."
    ".(int)$bu->derecelendirme."
  • "; } }

    Yöntem __toString() bir nesnenin bir dize olarak temsilini oluşturmak için kullanılır. Bu şekilde, teklifin başlığı ve oy sayısı dahil olmak üzere HTML işaretlemesini oluşturabiliriz.

    Yöntem __almak() bir dizi için tanımsız sınıf özelliklerine erişim sağlamak için kullanılır $veri. Bu, erişmek istiyorsak $nesne->öneri, ve bu özellik tanımlanmadıysa, diziden elde edilecektir. $veri ve varmış gibi geri döndü. Bu şekilde, tüm özellikleri ayarlamak yerine bir diziyi yapıcıya iletebiliriz. Bir nesne oluşturduğumuzda bu yaklaşımı kullanırız. ajax.php.

    Şimdi sayfa için sırasız bir liste oluşturmaya geçelim.

    demo.php

    "connect.php" gerektirir; "suggestion.class.php" gerektirir; // IP'yi sayıya çevir. Bu, veri tabanında IP // depolamanın daha verimli bir yoludur: $ip = sprintf("%u",ip2long($_SERVER["REMOTE_ADDR"])); // Aşağıdaki sorgu, // tüm teklifleri seçmek için sol birleştirmeyi kullanır ve aynı anda kullanıcının bunlara oy verip vermediğini belirler. $result = $mysqli->query(" SELECT s.*, if (v.ip IS NULL,0,1) have_voted FROM FROM s sol olarak JOIN öneri_oyları AS v ON(s.id = v.suggestion_id AND v. gün = CURRENT_DATE VE v.ip = $ip) ORDER BY s.rating DESC, s.id DESC "); $str = ""; if(!$mysqli->error) ( // UL $str üret = "
      "; // MySQL fetch_object yöntemini kullanarak yeni bir nesne oluşturun // ve onu sorgu sonucu sütunlarıyla doldurun: while($suggestion = $result->fetch_object("Öneri"))( $str.= $suggestion; // __toString yöntemini kullanın (). ) $str .="
    "; }

    İsteği yürüttükten sonra yöntemi kullanıyoruz getirme_nesnesi() nesne $sonuç. Bu yöntem, sorgu sonucunun her satırı için verilen sınıftan bir nesne oluşturur ve her satırın sütunlarını nesnenin genel özellikleri olarak atar.

    PHP ayrıca jQuery tarafından gönderilen AJAX isteklerini de yönetir. Bu uygulanır ajax.php. AJAX eylemlerini ayırmak için komut dosyası parametreyi kullanır. $_GET["eylem"], iki değerden birine sahip olabilen - ' oy' veya ' Sunmak‘.

    ajax.php

    "connect.php" gerektirir; "suggestion.class.php" gerektirir; // istek AJAX'tan gelmediyse, çıkın: if($_SERVER["HTTP_X_REQUESTED_WITH"] !="XMLHttpRequest")( çıkış; ) // IP'yi bir sayıya dönüştürün. Bu, IP'leri veritabanında saklamanın daha verimli bir yoludur: $ip = sprintf("%u",ip2long($_SERVER["REMOTE_ADDR"])); if($_GET["eylem"] == "oy")( $v = (int)$_GET["oy"]; $id = (int)$_GET["id"]; if($v != -1 && $v != 1)( çıkış; ) // Böyle bir öneri kimliğinin olup olmadığını kontrol edin: if(!$mysqli->query("Önerilerden 1'i SEÇ WHERE id = $id")->num_rows)( çıkış ; ) // id, ip ve gün alanları birincil anahtardır. // Yinelenen bir anahtar girmeye çalışırsak sorgu başarısız olur, // bu, kullanıcının günde yalnızca bir kez oy kullanabileceği anlamına gelir. $mysqli->query(" INSERT INTO notice_votes (suggestion_id,ip,day,vote) VALUES ($id, $ip, CURRENT_DATE, $v) "); if($mysqli->affected_rows == 1) ( $mysqli->query(" GÜNCELLEME önerileri SET " .($v == 1 ? "votes_up = oylar_yukarı + 1" : "votes_down = oylar_aşağı + 1").", derecelendirme = derecelendirme + $v WHERE id = $id "); ) ) else if($_GET[ " action"] == "gönder")( if(get_magic_quotes_gpc())( array_walk_recursive($_GET,create_function("&$v,$k","$v = stripslashes($v);")); ) / / İçeriğin çıkarılması $_GET["content"] = htmlspecialchars(strip_ etiketler($_GET["içerik"])); if(mb_strlen($_GET["içerik"],"utf-8")<3){ exit; } $mysqli->query("INSERT INTO öneri SET öneri = "".$mysqli->real_escape_string($_GET["içerik"])."""); // Yeni oluşturulan teklifin HTML kodunu JSON formatında çıktılayın. // __toString() sihirli yöntemini çağırmak için (string) kullanıyoruz. echo json_encode(array("html" => (string)(yeni Öneri(dizi("id" => $mysqli->insert_id, "öneri" => $_GET["içerik"]))))); )

    jQuery bir istek gönderdiğinde ' oy', hiçbir dönüş değeri beklenmiyor, bu nedenle komut dosyası hiçbir şey çıkarmaz. Sorulduğu zaman ' Sunmak', jQuery, henüz eklenen cümle için HTML işaretlemesini içeren bir JSON nesnesinin döndürülmesini bekler. Yeni nesnenin oluşturulduğu yer burasıdır. öneri sihirli yöntemi kullanarak __toString() ve işlevi kullanarak dönüştürme json_encode().

    jQuery

    Tüm jQuery kodu dosyada script.js. Kırmızı ve yeşil oklar için fare tıklama olaylarını dinler. Ancak cümle herhangi bir zamanda eklenebildiği için jQuery yöntemi kullanılır. canlı().

    script.js

    $(document).ready(function()( var ul = $("ul.suggestions"); // YUKARI veya AŞAĞI oklarını izleyin: $("div.vote span").live("click",function ( )( var elem = $(bu), parent = elem.parent(), li = elem.closest("li"), ratingDiv = li.find(".rating"), id = li.attr("id " ).replace("s",""), v = 1; // Kullanıcı zaten oy verdiyse: if(parent.hasClass("inactive")( return false; ) parent.removeClass("active"). addClass ("etkin değil"); if(elem.hasClass("down"))( v = -1; ) // Sağdaki artış sayacı: ratingDiv.text(v + +ratingDiv.text()); // Yerleştir tüm LI öğelerini bir dizide // ve oy sayısına göre sıralayın: var arr = $.makeArray(ul.find("li")).sort(function(l,r)( return +$(".rating") ,r).text () - +$(".rating",l).text(); )); // Sıralanmış LI öğelerini UL ul.html(arr); // AJAX isteği gönder $.get( "ajax.php" ,(action:"vote",vote:v,"id":id)); )); $("#suggest").submit(function()( var form = $(bu), textField = $(" #suggestionText"); // Yinelenen istekleri engelle: if(form.hasClass("working") || textField.val().length<3){ return false; } form.addClass("working"); $.getJSON("ajax.php",{action:"submit",content:textField.val()},function(msg){ textField.val(""); form.removeClass("working"); if(msg.html){ // Добавление разметки нового созданного элемента LI на страницу: $(msg.html).hide().appendTo(ul).slideDown(); } }); return false; }); });

    Oklardan birinde bir fare tıklaması olayı meydana geldiğinde, jQuery, sınıfın ayarlanıp ayarlanmadığını belirler. 'etkin değil' eleman üzerinde LI. Bu sınıf yalnızca, kullanıcı son gün içinde zaten oy vermişse öneriler için geçerlidir. Bu sınıf bir elementte mevcutsa LI fare tıklama olayı yok sayılır.

    Nasıl kullanıldığına dikkat edin $.makeArrayöğeleri içeren jQuery nesnelerini çevirmek için LI, bir diziye. Böylece sort yöntemini kullanabiliriz. dizi.sort() ve iki öğe alan özel bir işlev iletin LI ve karşılaştırılan öğelerin birbiriyle ilişkili olup olmamasına bağlı olarak negatif bir değer, sıfır veya pozitif bir değer verir. Bu dizi daha sonra sırasız bir listeye eklenir.

    css

    Artık tüm işaretlemelere sahip olduğumuza göre, şekillendirmeye başlayabiliriz. Genel olarak, stiller oldukça ilkeldir, tüm öğelerin sol üst ve sağ alt köşelerinin yuvarlanmasına dikkat etmeniz yeterlidir. Tüm CSS Stil Dosyası stiller.css Dersin kaynak kodunda mevcuttur.

    stiller.css

    .rounded, #suggest, .suggestions li( -moz-border-radius-topleft:12px; -moz-border-radius-bottomright:12px; -webkit-border-top-left-radius:12px; -webkit-border- alt-sağ-yarıçap:12px; kenar-sol-üst-yarıçap:12px; border-alt-sağ-yarıçap:12px; )

    Hazır!

    Çözüm

    Bu betiği sunucunuzda kullanmayı planlıyorsanız, dosyadaki SQL sorgu kodunu kullanarak iki tablo oluşturmanız gerekecektir. tablolar.sql phpMyAdmin'deki SQL sekmesine girilebilir. Ayrıca dosyadaki veritabanı bağlantı parametrelerinde değişiklik yapmanız gerekir. connect.php.

    Kullanıcılarınızdan öneriler toplamak için komut dosyasını kullanabilirsiniz. Ayrıca yeni teklif ekleme seçeneğini kapatabilir ve güzel bir oylama sistemi elde edebilirsiniz.