Ukryte funkcje PHP? [Zamknięte]


174

Wiem, że brzmi to jak dziwaczne pytanie, ale pozwól mi wyjaśnić, skąd pochodzę.

Po ukończeniu college'u dostałem pracę w sklepie PHP. Pracowałem tam półtora roku i pomyślałem, że nauczyłem się wszystkiego o programowaniu.

Potem dostałem pracę jako jednoosobowy wewnętrzny warsztat programistyczny w dużej korporacji, gdzie cała praca była w C #. W moim zaangażowaniu na to stanowisko zacząłem czytać mnóstwo blogów i książek i szybko zdałem sobie sprawę, jak bardzo się myliłem, myśląc, że wiem wszystko. Dowiedziałem się o testach jednostkowych, wzorcach wstrzykiwania zależności i dekoratorach, zasadzie projektowania polegającej na luźnym sprzężeniu, debacie na temat kompozycji nad dziedziczeniem itd., I tak dalej, i tak dalej, i dalej - nadal bardzo to wszystko pochłaniam. Nie trzeba dodawać, że mój styl programowania zmienił się całkowicie w ciągu ostatniego roku.

Teraz łapię projekt php, wykonując kodowanie dla start-upu znajomego i czuję się całkowicie ograniczony w przeciwieństwie do programowania w C #. Naprawdę przeszkadza mi to, że do wszystkich zmiennych w zakresie klasy należy się odwoływać, dodając „$ this->”. Denerwuje mnie, że żadne z IDE, które wypróbowałem, nie ma bardzo dobrej inteligencji i że moje metody testów jednostkowych SimpleTest muszą zaczynać się od słowa „test”. Doprowadza mnie do szału, że dynamiczne typowanie uniemożliwia mi niejawne określanie typu parametru, jakiego oczekuje metoda, i że musisz napisać instrukcję switch, aby wykonać przeciążenie metod. Nie mogę znieść, że nie możesz mieć zagnieżdżonych przestrzeni nazw i musisz użyć operatora :: do wywołania konstruktora klasy bazowej.

Teraz nie mam zamiaru rozpoczynać debaty PHP vs C #, raczej mam na myśli to, że jestem pewien, że są pewne funkcje PHP, o których albo nie wiem, albo o których nie wiem, ale nie używam ich poprawnie. Jestem osadzony w moim wszechświecie C # i mam problemy z widzeniem poza szklaną misą.

Więc pytam, jakie są twoje ulubione funkcje PHP? Jakie rzeczy możesz w nim zrobić, a czego nie możesz lub są trudniejsze w językach .Net?


Zepsuty paradygmat OO? Dla mnie to najgorsza „ukryta” funkcja, jaką odkryłeś.
KNOOPX

Te wątki są trochę zabawne ... Ponieważ dla zespołu, z którym pracuję, „ukryta funkcja” to fraza kodu oznaczająca „błąd”. I wiesz co ... Czasami odkrycie ukrytej funkcji niekoniecznie jest dobrą rzeczą ...
Ganesh Shankar,

@Ganesh one man's bug to kolejna ukryta funkcja mans ...
Xeoncross

Odpowiedzi:


328

Dokumentacja . Dokumentacja dostaje mój głos. Nie spotkałem się z bardziej szczegółową dokumentacją online dla języka programowania - wszystko, co muszę złożyć razem z różnych witryn internetowych i stron podręcznika.


60
Zgadzam się. Możliwość wpisania www.php.net/nazwa_funkcji i otrzymywanie odnośników przez większość czasu jest świetna.
Allain Lalonde,

1
To świetna funkcja PHP, ale tak naprawdę nie nazwałbym jej ukrytą ... Jeśli kiedykolwiek szukałeś w Google parametrów metod itp., Skończyłbyś na php.net.
John Bubriski

27
Ja też się zgadzam. Największą zaletą instrukcji są komentarze użytkowników. Rzadko kiedy widziałem inne dokumentacje, które to mają. Mogą zawierać prawdziwe klejnoty. Jedynym minusem jest to, że IMHO są przycinane trochę za wcześnie.
Sander Marechal

3
@Phoexo "trochę mniej czytelny" ??? Nigdy nie rozumiałem i nigdy nie zrozumiem MSDN, podczas gdy dokumenty PHP są łatwe i przejrzyste.
Lauriys

3
Nie zgadzać się. Jedynym powodem, dla którego dokumentacja jest „dobra” jest to, że niektóre komentarze użytkowników zapełniają wszystkie dziury w oficjalnych notatkach.
Rob Howard

179

Tablice . Sądząc po odpowiedziach na to pytanie, nie sądzę, aby ludzie w pełni doceniali, jak łatwe i użyteczne są tablice w PHP. Tablice PHP działają jednocześnie jako listy, mapy, stosy i ogólne struktury danych. Tablice są zaimplementowane w rdzeniu języka i są używane w dowolnym miejscu, co skutkuje dobrą lokalizacją pamięci podręcznej procesora. Perl i Python używają oddzielnych konstrukcji językowych dla list i map, co powoduje więcej kopiowania i potencjalnie mylących przekształceń.


11
Elementy tablicy PHP są uporządkowane.
user8134

117
Moje pierwsze przejście z PHP na C # prawie mnie zabiło. W języku C # tablice są po prostu prostą strukturą o statycznym rozmiarze i indeksie liczbowym. W PHP tablice są taśmą klejącą wszechświata!
Dinah,

4
Również się zgadzam. Kiedy bawiłem się Javą na uniwersytecie, byłem zdumiony ich sztywnością, brakiem elastyczności. Naprawdę doceniłem to, jak dobre są tablice PHP.
Christian

11
Jestem pewien, że tablice php są świetne, ale 40 głosów na komentarz, który powala tablice C #? Jeśli tablica C # nie spełnia potrzeb, istnieje wiele opcji. ArrayList i kolekcje ogólne mają bardzo duże możliwości. Istnieje wiele rodzajów kolekcji dla określonych potrzeb. Jedyną faktyczną zaletą php pod tym względem jest to, że nie zapewnia żadnych opcji, z których programista musi decydować. Albo używasz tablicy, albo nie masz zmiennej indeksowalnej.
G-Wiz,

24
Z drugiej strony składnia tablic jest do niczego. W wielu językach skryptowych można utworzyć prostą tablicę 2D tak: [[1, 2], [3, 4]]porównaj to do wersji PHP array(array(1, 2), array(3, 4)).
Rene Saarsoo

167

Programy obsługi strumienia umożliwiają rozszerzenie „systemu plików” o logikę, która, o ile wiem, jest dość trudna do wykonania w większości innych języków.

Na przykład za pomocą programu obsługi MS-Excel Stream możesz utworzyć plik MS Excel w następujący sposób:

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

Uważam, że framework KIO również na to pozwala, ale jest to dostępne tylko dla aplikacji komputerowych opartych na KDE.
MiffTheFox

21
IMHO posiadanie odpowiedniego podejścia OO byłoby znacznie bardziej rozsądne niż ten bałagan z programami obsługi strumienia. Tak, ładnie jest móc czytać / pisać pliki Excela, ale czy to musi tak działać?
Anti Veeranna

3
Może tak, ale takie podejście obejmuje złożoność interfejsu, który jest wspólny dla większości programistów PHP ... bez konieczności uczenia się pojęć zorientowanych obiektowo, które mogą ich przekraczać.
Allain Lalonde

13
Jeśli pracujesz z Amazon S3, sprawdź Zend_Amazon_S3, który zapewnia interfejs strumieniowy dla adresów URL, takich jak „s3: // {nazwa-zasobnika} / ścieżka”.
davidtbernal

Użyłem tego do stworzenia prostego DSL dla mojej warstwy widoku, po prostu czytając plik PHP, wykonując zamiennik ciągu i przekazując go przez eval (). Np. Zrobiłem to w taki sposób, że mogę używać krótkich tagów, gdy tylko zdecyduję, i robić @ -> someVar, aby mieć dostęp do danych na poziomie widoku.
Jasper Bekkers

131

Metody magiczne to metody awaryjne, które są wywoływane między innymi za każdym razem, gdy wywołujesz metodę, która nie istnieje, przypisujesz lub odczytujesz właściwość, która nie istnieje.

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

Programista C ++ może zauważyć, że PHP pozwala na przeciążanie niektórych operatorów, np . ()Lub (string). Właściwie PHP pozwala na jeszcze większe przeciążenie, na przykład []operator ( ArrayAccess ), foreachkonstrukcja języka ( Iterator i IteratorAggregate ) oraz countfunkcja ( Countable ).


4
Jako przydatny przykład tego, co można osiągnąć za pomocą magicznych metod, goto phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom

6
Nie zgadzać się. Jest to znacznie słabsze niż podobne funkcje w Smalltalk, Ruby i Pythonie (i prawdopodobnie zostało skopiowane z jednego z nich)
finnw

34
Fakt, że implementacja tej funkcji w PHP jest słabsza niż w innych językach, nie czyni jej mniej użyteczną w PHP.
Allain Lalonde

2
__call()jest świetny w frameworkach z map domain.com/controller/method/
alex

7
Magiczne metody są również powolne jak diabli. Używaj ich ostrożnie.
Alex Weinstein

95

Średnia klasa jest czysty pojemnik. Dopiero niedawno się o tym dowiedziałem.

Zamiast używać tablicy do przechowywania atrybutów serwerowych

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

Możesz użyć standardowej klasy

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

Jest to szczególnie przydatne podczas uzyskiwania dostępu do tych zmiennych w ciągu

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

43
„{$ person ['name']} ma {$ person ['age']} lat”.
Kornel

27
„osoba [imię] to $ osoba [wiek] lat” również zadziała ... Bez cudzysłowów, bez nawiasów klamrowych :)
majelbstoat

16
$ string = sprintf ("% s ma% d lat.", $ person ['imię'], $ osoba ['wiek']);
Daniel Sloof

60
Skoro już o tym mowa: (object) array ("name" => 'bob', 'age' => 5)
Annika Backstrom

30
@majelbstoat: Usunięcie cudzysłowów spowolniłoby działanie skryptu, ponieważ interpreter PHP będzie sprawdzał, czy „imię” i „wiek” zostały ustawione za pomocą funkcji define (...). Jest to również zła praktyka, biorąc pod uwagę, że możliwe byłoby całkowite odwrócenie klawiszy, do których uzyskuje się dostęp w każdym przypadku: define ('wiek', 'imię'); define ('imię', 'wiek');
brianreavis

90

Pliki dołączane mogą mieć wartość zwracaną, którą można przypisać do zmiennej.

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

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

@Peter BARDZO przydatne do obsługi błędów wyjątków db-> localhost.
Talvi Watia

Jest to wygodne do skonfigurowania szybkiego i brudnego pliku konfiguracyjnego.
Frank Farmer

Dlaczego zwracasz tę tablicę? Jeśli dołączony plik zawiera tablicę, można jej użyć natychmiast po dołączeniu.
fabrik,

5
@fabrik, ponieważ byłaby to zmienna globalna i dostępna w całym głównym zakresie. To dość nieprzyjemne, to jest o wiele lepsze.
Mikulas Dite

Pracowałem nad projektem we frameworku Yii i ten projekt ma plik konfiguracyjny, w którym tablica została zwrócona w ten sposób, teraz rozumiem, dlaczego plik był taki.
Deweloper Simer Twilio Toronto

83

Możesz wykorzystać fakt, że oroperator ma niższy priorytet niż =to zrobić:

$page = (int) @$_GET['page'] 
  or $page = 1;

Jeśli wartość pierwszego przypisania ma wartość true, drugie przypisanie jest ignorowane. Inny przykład:

$record = get_record($id) 
  or throw new Exception("...");

7
Myślę, że nie jestem do końca przekonany; chociaż wydaje się, że nie jest podatny na błędy, jest sprzeczny z intuicją, a to samo w sobie może sprzyjać błędom.
thomasrutter

14
@Pies: jeden sposób jest następujący, szczerze mówiąc dość niechlujny kod: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['page']: 1; // Zaletą tego jest to, że nie jest wymagane tłumienie błędów.
DisgruntledGoat

3
po zastanowieniu, ponieważ szukasz liczby całkowitej, której możesz użyć zamiast: $ page = is_int ($ _ GET ['page'])? $ _GET ['page']: 1;
DisgruntledGoat

4
Warto zauważyć, że kod następujący po nim orzostanie wykonany, jeśli kod poprzedzający zwróci orwartość liczbową 0. Tak więc semantycznie może być mniej prawdopodobne w przypadku czegoś takiego $_GET['page'], ale oczywiście taka okoliczność może się zdarzyć i dobrze jest na to uważać.
powiek

3
Warto również zauważyć, że oroperator jest wersją operatora o niższym precedensie ||. Poza tym +1, ponieważ jest to bardzo wyraziste i często zapominam, że jest to możliwe. Powinien być używany częściej i jest absolutnie jasny w tym, co robi. Nie wiem jednak, jak kodują „prawdziwi mężczyźni”, więc nie mogę tego komentować.
powiek

80

__autoload() (klasowe) pliki wspomagane przez set_include_path() .

W PHP5 nie ma teraz potrzeby określania długich list instrukcji „include_once” podczas wykonywania porządnego OOP.

Po prostu zdefiniuj mały zestaw katalogów, w których pliki bibliotek klas mają rozsądną strukturę i ustaw ścieżkę automatycznego dołączania:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Teraz __autoload()rutyna:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Teraz PHP zautomatyzuje dołączanie potrzebnych plików na żądanie, oszczędzając czas analizy i pamięć.


czy spl_autoload_register () jest lepszy w użyciu?
Alex

19
Oczywiście! __autoload () to PHP4, ale spl_autoload_register () to nieinwazyjne „łączenie łańcuchowe” metod automatycznego ładowania.
Willem

3
Przydatna funkcja, ale jedynym zastrzeżeniem jest to, że gdy znajdujesz instancję danej klasy, nieco trudniej jest znaleźć lokalizację pliku klasy. Jawne zdefiniowanie dołączeń na górze daje skończoną listę zaangażowanych klas i ich dokładną lokalizację.
Cory House

To fajna funkcja, ale tylko po to, aby ominąć sytuację, w której kod nie jest prekompilowany, więc nie wie, gdzie będzie ta klasa. Dużym minusem jest to, że nie możesz mieć 2 klas o tej samej nazwie, nawet jeśli znajdują się one w różnych przestrzeniach nazw.
Kibbee

3
Proszę spojrzeć na propsal PSR-0 od PHP Standards Working Group (obejmującego twórców ZF, Symfony, Doctrine, CakePHP, Solar itp.) Podczas implementacji automatycznego ładowania: groups.google.com/group/php-standards/web / psr-0-final-offer
Philippe Gerber

76

Łatwość . Największą cechą jest to, jak łatwo nowi programiści mogą usiąść i napisać „działające” skrypty i zrozumieć kod.

Najgorszą cechą jest to, jak łatwo nowi programiści mogą usiąść i napisać „działające” skrypty i myśleć, że rozumieją kod.

Otwartość społeczności otaczającej PHP i ogromne ilości projektów PHP dostępne jako open-source jest o wiele mniej skomplikowane dla kogoś wchodzącego świat rozwoju i jak ty, może być odskocznią do bardziej dojrzałych języków.

Nie będę debatował nad kwestiami technicznymi, tak jak wiele osób przede mną, ale jeśli spojrzysz na PHP jako na społeczność, a nie język sieciowy, społeczność, która wyraźnie cię przyjęła, gdy zacząłeś tworzyć, korzyści naprawdę mówią same za siebie.


3
Zdecydowanie dobry komentarz. Python był moim pierwszym językiem i był niesamowity, ale brak projektów, które czułam, że byłbym w stanie zrozumieć, stworzył barierę. Dzięki PHP mogę znaleźć prawie wszystko w dokumentacji i to rozgryźć ... zasoby dostępne w sieci są niesamowite.
dscher

76

Zmienne zmienne i funkcje bez wątpienia!

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

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

To samo dotyczy parametrów obiektu ($ jakiś_obiekt -> $ jakaś_zmienna);

Bardzo bardzo dobrze. Kodowanie w Make z pętlami i wzorami jest bardzo łatwe, szybsze i bardziej kontrolowane niż eval (Thanx @ Ross & @Joshi Spawnbrood!). T


111
zmienne zmienne faktycznie sprawiają, że kod jest mniej czytelny i bardziej podatny na błędy.
Elzo Valugi

8
A ludzie naprawdę tego używają? Stary, nie chciałbym czytać tych źródeł.
Gary Willoughby,

27
Zmienne zmienne to jedna z najgorszych funkcji oferowanych przez PHP.
davidtbernal

10
9 Na 10 przypadków zmienne zmienne lepiej zastępować tablicami, aby wszystkie dane były w jednym miejscu, można je iterować i tak dalej. Tylko w bardzo szczególnych okolicznościach mogą być przydatne.
Jasper Bekkers,

7
Prosimy nie zmuszać nowicjuszy do korzystania z tej „funkcji”.
whiskeysierra

68

Możesz używać funkcji z niezdefiniowaną liczbą argumentów za pomocą func_get_args().

<?php

function test() {

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

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

?>

1
Właśnie miałem to opublikować. Coś jak właściwość arguments w funkcjach JS.
Alex

67

Uwielbiam zdalne pliki . W przypadku tworzenia stron internetowych ten rodzaj funkcji jest wyjątkowo przydatny.

Chcesz popracować nad zawartością strony internetowej? Prosty

$fp = fopen('http://example.com');

i masz gotowy uchwyt pliku, tak jak każdy inny normalny plik.

A co powiesz na odczytanie zdalnego pliku lub strony internetowej bezpośrednio w ciągu?

$str = file_get_contents('http://example.com/file');

Trudno przecenić przydatność tej konkretnej metody.

Chcesz przeanalizować zdalny obraz? Co powiesz na zrobienie tego przez FTP?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

Prawie każda funkcja PHP, która działa z plikami, może współpracować z plikiem zdalnym. Można nawet include()czy require()pliki z kodem zdalnie ten sposób.


2
To takie miłe! Aby to zrobić na przykład w Javie, musisz dołączyć gazylion plików jar, a następnie napisać dużo standardowego kodu.
Kimble

16
„W ten sposób można nawet zdalnie dołączać () lub wymagać () plików kodu”. Oczywiście umieszczanie () pliku na serwerze, którego nie kontrolujesz, to okropny, okropny pomysł.
Frank Farmer

4
@Frank - tak, cóż, można by przypuszczać, że dołączasz kod z serwera, który kontrolujesz.
zombat

1
Chodzi o to, że zdalne włączanie plików jest częstym problemem bezpieczeństwa PHP: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Frank Farmer,

63

strtr ()

Jest niesamowicie szybki, tak bardzo, że byłbyś zdumiony. Wewnętrznie prawdopodobnie używa jakiejś szalonej struktury typu b-tree, aby uporządkować twoje dopasowania według ich wspólnych przedrostków. Używam go z ponad 200 ciągami znajdowania i zamieniania, a nadal przechodzi przez 1 MB w mniej niż 100 ms. Dla wszystkich, z wyjątkiem trywialnie małych łańcuchów, strtr () jest nawet znacznie szybszy niż strtolower () w robieniu dokładnie tego samego, nawet biorąc pod uwagę zestaw znaków. Prawdopodobnie mógłbyś napisać cały parser używając kolejnych wywołań strtr i byłby to szybszy niż zwykłe dopasowanie wyrażenia regularnego, ustalenie typu tokenu, wyświetlenie tego lub innego, następnego rodzaju wyrażenia regularnego.

Pisałem normalizator tekstu do dzielenia tekstu na słowa, małych liter, usuwania interpunkcji itp., A strtr był moim szwajcarskim scyzorykiem, pokonał spodnie z wyrażeń regularnych, a nawet str_replace ().


1
Prawdopodobnie jest szybszy, ponieważ zastępuje pojedyncze znaki.
staticsan

10
strtr () nie tylko zastępuje pojedyncze znaki. Może zastąpić podciągi o dowolnej długości innymi podciągami o dowolnej długości i nadal wydaje się naprawdę szybki.
thomasrutter

1
Wspomniałeś, że w niektórych przypadkach był szybszy niż strtolower, czy możesz to udowodnić? Zrobiłem mały test porównawczy i stwierdziłem, że jest fałszywy.
The Pixel Developer

1
Zauważyłem, że na małych ciągach, powiedzmy 80 znaków, był wolniejszy niż strtolower, a na dużych, powiedzmy 1 MB, był szybszy. Prawdopodobnie za każdym razem, gdy jest wywoływana, występuje pewien koszt stały. Po prostu używałem strtr ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); Ciąg, na którym operowałem, był typowym angielskim tekstem („Szybki brązowy lis”, coś w tym rodzaju).
thomasrutter

Właśnie przeczytałem ten post, a potem przeszukałem go trochę i znalazłem: simplemachines.org/community/index.php?topic=175031.0 Masz jakiś pomysł, który z nich jest właściwy?
Flipper,

61

Jedną z niezbyt znanych funkcji PHP jest extract()funkcja, która rozpakowuje tablicę asocjacyjną do lokalnej przestrzeni nazw. Prawdopodobnie istnieje to w przypadku aborminacji autoglobalnej, ale jest bardzo przydatne do tworzenia szablonów:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Teraz możesz użyć render_template('index.html', array('foo' => 'bar'))i tylko $fooz wartością "bar"pojawia się w szablonie.


15
Miałem zamiar złościć się na ciebie za to, że sugerujesz, że ekstrakt () w jakikolwiek sposób był dobrą funkcją. Ale myślę, że to użycie jest całkiem przydatne. Przypuszczam, że to jedyny raz, kiedy go użyłem, i to dobry pomysł!
thomasrutter

5
extract () sprawia, że ​​zwijanie własnego, niezwykle lekkiego systemu szablonów jest bardzo proste. +1
Dinah,

14
Jej odwrotność, compact (), również jest fajna: $ a = 1; $ b = 2; kompaktowy („a”, „b”); // == array ('a' => $ a, 'b' => $ b)
Annika Backstrom

2
Tak, to prawdopodobnie jedyne naprawdę dobre użycie extract ().
staticsan

4
Sugerowałbym, aby w tym przypadku nie używać zwykłych słów jako nazw argumentów funkcji, ponieważ kontekst $, z którego wyodrębniasz (), może zawierać wartości w indeksach „as_string” lub „template_name”. Użycie EXTR_SKIP jest dopuszczalne, ale przenosi problem tylko w inne miejsce (tj. Jeśli szablon oczekuje na $ as_string to otrzyma dla niego niepoprawną wartość.)
Michał Tatarynowicz

52

Zakres () nie jest ukryty sam w sobie, ale nadal widzę wiele osób wykonujących iteracje z:

for ($i=0; $i < $x; $i++) { 
    // code...
}

kiedy mogą używać:

foreach (range(0, 12) as $number) {
    // ...
}

Możesz też robić proste rzeczy, takie jak

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

3
możesz zrobić foreach (tablica $ jako $ klucz => $ wartość) {}, co jest jeszcze prostsze.
SilentGhost

15
Może to być mikro-optymalizacja, ale warto zauważyć, że przez pewien czas są one znacznie szybsze i mniej wymagające pamięci niż wszystkie.
JAL

3
Powinieneś wypróbować Pythona. Jest to tak proste, jak „for i in range (12)” lub możesz użyć bardziej wydajnego xrange.
Ponkadoodle

2
@SilentGhost: nadal potrzebujesz tablicy na początek, co nie zawsze ma miejsce. @Newbie: opracuj proszę?
Alec,

1
@flexxy, oczywiście, NIE jest. Rozważ to: phpbench.com przewiń w dół do Read Loop.
Kolego

44

Przestrzeń internetowa obsługująca PHP jest zwykle tańsza niż przestrzeń z (asp) .net. Państwo może nazwać funkcją ;-)


3
Dużo taniej jest też skonfigurować wiele serwerów, jeśli nie musisz płacić za system Windows Server na każdym z nich.
MiffTheFox

4
Jedynym miejscem, w którym wiem, gdzie Windows jest opłacalny, jest uniwersytet, który otrzymuje zniżki STEEEEP na oprogramowanie serwera w takim stopniu, w jakim taniej jest dla mojego działu kupić 100 kopii systemu Windows niż szkolenie naszych administratorów na Linuksie (co częściowo zasmuca mnie, ale ich konfiguracja systemu Windows jest czysta i dobrze skonfigurowana).
dcousineau

4
Na razie, ale przełączenie trzeba dokonać tylko raz, a prędzej czy później trzeba będzie kupić nowe licencje ...
e-satis

42

Słowo statickluczowe jest przydatne poza punktem widzenia OOP. Możesz szybko i łatwo wdrożyć `` zapamiętywanie '' lub buforowanie funkcji za pomocą czegoś tak prostego, jak:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

Słowo statickluczowe tworzy zmienną, która utrzymuje się tylko w zakresie tej funkcji po wykonaniu. Ta technika jest świetna w przypadku funkcji, które trafiają do bazy danych, takie jak get_all_books_by_id(...)lub get_all_categories(...)wywoływane więcej niż raz podczas ładowania strony.

Uwaga: upewnij się, że znalazłeś najlepszy sposób na utworzenie klucza do swojego skrótu, w prawie każdych okolicznościach md5(...)powyższe NIE jest dobrą decyzją (problemy z szybkością i długością wyjścia), użyłem go do celów ilustracyjnych. sprintf('%u', crc32(...))lub spl_object_hash(...)może być znacznie lepsza w zależności od kontekstu.


7
Tylko skopiowana funkcja z C / C ++
GetFree

2
@GetFree Nie sądzę, aby ktokolwiek zaprzeczył, że prawie całe PHP zostało skopiowane z C, C ++, Perla itp.
Frank Farmer

1
Kopiowanie to najlepsza rzecz, jaką można zrobić.
NikiC,

1
Zły PHP. Zawsze kopiuje funkcje od innych. Zamiast tego powinien napisać wszystko od zera! (W przypadku najmniejszej możliwości potraktowania tego poważnie: żartuję)
Halil Özgür

42

Jedną z fajnych funkcji PHP jest CLI . Nie jest to tak „promowane” w dokumentacji, ale jeśli potrzebujesz rutynowych skryptów / aplikacji konsolowych, użycie cron + php cli jest naprawdę szybkie!


Naprawdę powinienem się temu przyjrzeć, mam kilka zadań crona, które pobierają skrypt PHP za pośrednictwemwget http://example.com...
DisgruntledGoat

CLI to także doskonały sposób na wykrywanie błędów, ponieważ ostrzeżenia / błędy będą wyświetlane bez konieczności zmiany preferencji raportowania błędów.
Glacials

40

Następnie sztuczka „i drukuj”

<?php $flag and print "Blah" ?>

Powoduje echo Blah, jeśli $ flag jest prawdziwe. NIE DZIAŁA Z ECHO.

Jest to bardzo przydatne w szablonie i zastępuje? : które nie są łatwe do odczytania.


24
Osobiście uważam, że operator trójskładnikowy jest znacznie bardziej oczywisty niż wykorzystanie zwarcia oceny logicznego i.
Vicent Marti

26
W rzeczywistości jest to taka sama liczba znaków, jak w <? Php if ($ flag) print "Bla"
za dużo php

3
Nawiasy nie są tak łatwe do wpisania jak „i”, zwłaszcza na mojej cholernej francuskiej klawiaturze ;-)
e-satis

7
@all comments - nie chodzi o to, jak krótko możesz to zrobić! Chodzi o czytelność i łatwość obsługi dla osób korzystających z szablonów, które czasami nie są nawet programistami.
Tor Valamo,

6
Chciałbym skomentować, że instrukcja if () jest łatwiejsza i bardziej czytelna. Z pewnością łatwiej jest mi się rozszyfrować niż wykorzystywanie zasadniczo efektu ubocznego operatora „and” w PHP, gdzie łatwo jest popełnić błąd (lub wygląda na to, że jest to pomyłka, gdy później czytasz kod). Na przykład, jak stwierdzono, nie będzie to działać tak, jak chcesz z „echo”. W przypadku if () nie ma takich pułapek.
thomasrutter

37

Możesz użyć znaku minus w nazwach zmiennych, takich jak ta:

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

Po co go używać? Nie mam pomysłu: może na model CSS? Lub jakiś dziwny JSON, który musisz wydrukować. To dziwna funkcja :)


2
Czy to działa z nazwami metod? Może być przydatny dla frameworków, które używają routera i chcę domain.com/something-with-minuses/view/
alex

6
Nawiasy klamrowe umożliwiają dostęp do właściwości obiektów, które zawierają myślniki, kropki i inne elementy niealfanumeryczne. Jednym z powodów, dla których warto go używać, jest XML, gdzie nazwy encji mogą być kropkowane, jak w NITF / NewsML <body.content>. Jeśli używasz SimpleXML, uzyskasz do niego dostęp w ten sposób $item->DataContent->body->{'body.content'}.
Jesse Kochis

2
Zmienne PHP mogą przyjmować dowolne znaki, gdy są używane w ten sposób, nawet spacje i znaki nowej linii.
Nowicjusz

Byłoby to bardzo przydatne podczas używania w SimpleXML ... awesome. Dzięki za udostępnienie.
KyleFarris

34

Składnia HEREDOC to moja ulubiona ukryta funkcja. Zawsze trudne do znalezienia, ponieważ nie możesz użyć Google dla <<<, ale zapobiega to ucieczce z dużych fragmentów HTML i nadal pozwala upuszczać zmienne do strumienia.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

2
HEREDOC to mój ulubiony sposób tworzenia i używania instrukcji SQL.
bdl

11
Uwaga: zamykająca EOM; nie może być wcięty.
micahwittman,

Dobrze, ale bez sensu, jeśli używasz szablonów. Dodatkowo przeszkadza w prawidłowym wcięciu.
Manos Dilaverakis

7
Drogi Boże, to najbrzydszy fragment kodu, jaki kiedykolwiek widziałem. Jeśli używasz HEREDOC, to nie oddzieliłeś prezentacji od logiki.
Lotus Notes

@Byron: Nie musisz go używać do prezentacji, można go użyć do dowolnego ciągu. Zobacz komentarz bdl.
Tom Pažourek

34

Zapewne niewielu wie, że można określić stałe "zmienne" jako wartości domyślne dla parametrów funkcji:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Ciągów można używać tak, jakby były tablicami :

$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"

3
Ten ostatni jest fajny. Chociaż nie mam pojęcia, kiedy byłoby to lepsze niż inna metoda usuwania postaci. Jednak +1
George Mauer

3
Jest to prawdopodobnie bardziej wydajne niż wywołanie funkcji, aby to zrobić. Łańcuchy są zwykle przechowywane w pamięci w sposób ciągły, więc dotarcie do $ str [4] jest trywialne. Przechowywanie ciągów znaków jako tablic znaków jest powszechne w większości języków pochodzących z języka C.
sjobe

1
Nie musisz używać zdefiniowanej stałej jako wartości domyślnej. Doskonale sprawdza się również: function foot ($ param1, $ default = array ('key' => 'value'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Jednak masz rację, zauważając, że nie możesz użyć zmiennej jako argumentu domyślnego.
dcousineau

@dcousineau Twój przykład jest całkowicie poprawny, ponieważ array () nie jest funkcją, ale konstrukcją języka. Wywołania funkcji nie są dozwolone jako wartości domyślne argumentów.
Jamol,

4
Uważaj, aby traktować ciągi jako tablice, jeśli masz ciągi wielobajtowe (języki obce itp.)
philfreo

33

Najbardziej użyteczną rzeczą w kodzie PHP jest to, że jeśli nie rozumiem funkcji, którą widzę, mogę ją sprawdzić za pomocą przeglądarki i wpisując:

http://php.net/function

W zeszłym miesiącu widziałem funkcję „range” w jakimś kodzie. To jedna z setek funkcji, których udało mi się nigdy nie użyć, ale okazały się naprawdę przydatne:

http://php.net/range

Ten adres URL jest aliasem dla http://us2.php.net/manual/en/function.range.php . Ten prosty pomysł mapowania funkcji i słów kluczowych na adresy URL jest niesamowity.

Chciałbym, żeby inne języki, frameworki, bazy danych, systemy operacyjne miały równie prosty mechanizm wyszukiwania dokumentacji.


5
range()może się przydaćforeach( range(1, 10) as $i) { };
alex

Jeśli masz FireFox; po prostu wpisz PHP functionw pasku adresu, a wyszuka w Google „Szczęśliwy traf” i prawie zawsze trafisz na właściwą stronę dokumentacji php.
Kolky

30

Szybkie komentarze blokowe

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

Te komentarze umożliwiają przełączanie, jeśli blok kodu jest komentowany jednym znakiem.


14
To nie jest specyficzne dla PHP. Działa to w każdym języku, który obsługuje // ...komentarze do linii i /* ... */komentarze blokowe.
Jordan Ryan Moore

wszelkie narzędzia do czyszczenia kodu w końcu nienawidzą cię za używanie tego ...;)
Talvi Watia

3
Użyłem też /** /przed i /**/po. Możesz przełączyć blok, usuwając i dodając spację w pierwszym. Ma to dodatkową zaletę pracy z CSS (i innymi językami, które nie obsługują // ... komentarzy).
kingjeffrey

FWIW, link do oryginalnego artykułu aleembawany.com/2009/01/27/lazy-block-comment-trick
aleemb

@aleemb, powstrzymaj się od dalszych zmian w tym pytaniu.
Sam152

29

Moja lista… większość z nich należy raczej do „ukrytych funkcji” niż do „ulubionych funkcji” (mam nadzieję!), I nie wszystkie są przydatne, ale… tak.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

Możesz także zagnieżdżać operatory trójskładnikowe, czasami się przydaje.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Dobra, na razie przestanę :-)


Hmm, minęło trochę czasu ...

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

Właśnie odkryłem, że możesz przekazać dowolny ciąg jako nazwę metody, JEŚLI umieścisz go w nawiasach klamrowych. Nie możesz niestety zdefiniować żadnego łańcucha jako metody, ale możesz je złapać za pomocą __call () i przetworzyć je dalej w razie potrzeby. Hmmm....

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

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

Znalazłem ten mały klejnot w komentarzach Reddit:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

Nie można wywoływać funkcje wewnątrz {} tak bezpośrednio, ale mogą używać zmiennych-Holding-the-function-name i nazywają tych! (* i * możesz na nim również używać zmiennych zmiennych)


2
Proszę nie nadużywać trójskładnikowego operatora porównania; prowadzi to do zaciemnienia kodu.
staticsan

Łał. To może całkowicie zawęzić listę $ GLOBALS. Zła praktyka. Poważnie.
Talvi Watia

Czy istnieje już zawoalowany konkurs PHP?
Lotus Notes

Cóż, sztuczka z zamianą - imponująca i przydatna, dzięki.
OZ_

1
${''} = 456;hahaha .... całkiem nadużycie.
Skurmedel

26

Manipulacja tablicą.
Mnóstwo narzędzi do pracy z tablicami i manipulowania nimi. Może nie jest to unikalne dla PHP, ale nigdy nie pracowałem z językiem, który by to ułatwiał.


jak na przykład? Wydaje mi się, że wszystkie funkcje są niezgrabnie nazwane i umieszczone w globalnej przestrzeni nazw. Poza tym nie przychodzi mi do głowy nic, co nie byłoby tak proste w innym języku, z wyjątkiem może $ arr [] = $ newvalue do dodawania wartości - to super
George Mauer

8
Cóż, tablica PHP jest strukturą danych, która może być łatwo używana jako stos, kolejka, deque, lista, hashtable itp. Jest rzeczywiście dość elastyczna dla większości typowych potrzeb, bez uciekania się do czegokolwiek poza funkcjami array_ *.
Camilo Díaz Repka,

6
Python robi tablice (jako listy i krotki) znacznie lepiej niż PHP.
za dużo php

26

Jestem trochę taki jak Ty, kodowałem PHP od ponad 8 lat. Musiałem wziąć udział w kursie .NET / C # około rok temu i bardzo podobał mi się język C # (znienawidzony ASP.NET), ale dzięki temu stałem się lepszym programistą PHP.

PHP jako język jest dość kiepski, ale jestem z nim niezwykle szybki, a stos LAMP jest niesamowity. Produkt końcowy znacznie przewyższa sumę części.

To powiedziawszy, w odpowiedzi na twoje pytanie:

http://uk.php.net/SPL

Uwielbiam SPL , klasa kolekcji w C # była czymś, co mi się spodobało, gdy tylko zacząłem. Teraz mogę wziąć ciasto i je zjeść.

Andrzej


24

Jestem trochę zaskoczony, że nikt jeszcze o tym nie wspomniał, ale jedną z moich ulubionych sztuczek z tablicami jest użycie operatora plus. To jest trochę jak, array_merge()ale trochę prostsze. Odkryłem, że zwykle tego chcę. W efekcie pobiera wszystkie wpisy z RHS i sprawia, że ​​pojawiają się one w kopii LHS, w razie potrzeby nadpisując (tj. Nie są przemienne). Bardzo przydatne do rozpoczynania od tablicy „domyślnej” i dodawania niektórych rzeczywistych wartości w jednym trafieniu, pozostawiając wartości domyślne na miejscu dla wartości niedostarczonych.

Żądana próbka kodu:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );

$defaultspowinno być$control_defaults
diEcho Kwietnia

3
Myślę, że nie jest to tak jasne, jak array_merge, gdy masz dużo kodu do utrzymania. Przynajmniej, kiedy używasz funkcji array_merge, jest oczywiste, że masz do czynienia z tablicami.
Sylvain

A fakt, że robisz, ... + array( ...nie wystarczy, aby to wskazać? :-)
staticsan

Jakiej wersji PHP potrzebujesz do tego?
Lotus Notes

Jest to świetna funkcja i należy zauważyć, że tablica po „prawej” stronie znaku „+” nie nadpisze istniejących kluczy tablicy na „lewą” stronę znaku „+”.
Wil Moore III

21

Oto jedno, podoba mi się, jak ustawianie wartości domyślnych parametrów funkcji, które nie są dostarczane, jest znacznie łatwiejsze:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

4
Co zabawne, w zeszłym tygodniu widziałem tę „ukrytą funkcję” w Czytniku Google. Nie rozumiem, co jest w tym ukryte - to podstawowa składnia. Spróbuj na przykład ($ var = true).
Ross

8
Łatwiej niż co? Większość języków ma tę funkcję.
Christian Davén,

10
Łatwiejsze niż C # (i myślę, że C ++ i Java)
George Mauer

8
C ++ obsługuje domyślne wartości parametrów.
sjobe

2
c # w ogóle nie obsługuje wartości domyślnych. musisz napisać przeciążoną funkcję i zawsze deklarować wartość, która jest po prostu uciążliwa
DeveloperChris

21

Szybko i brudno to ustawienie domyślne.
Język jest pełen przydatnych skrótów, dzięki czemu PHP jest idealnym kandydatem do (małych) projektów, które mają krótki czas wprowadzenia na rynek. Nie znaczy to, że czysty kod PHP jest niemożliwy, wymaga po prostu dodatkowego wysiłku i doświadczenia.

Ale uwielbiam PHP, ponieważ pozwala mi wyrazić to, czego chcę, bez pisania eseju.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAWA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

I tak, obejmuje to nie wpisywanie Int .


4
zamiast tego powinieneś użyć strpos: if (false! == strpos ("one cat", "cat")) {
OIS

17
@OIS celem tego przykładu było zilustrowanie i porównanie przebiegu szybkiego dopasowania wyrażenia regularnego, a nie znalezienie ciągu „kot” w „jednym kocie”.
dcousineau

19
Java: if (Pattern.matches ("kot", "jeden kot")) {// zrób coś} Przestań narzekać na Javę, jeśli jej nie znasz.
whiskeysierra

3
+1 Willi jak to zrobić preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Wybierz ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); w Javie? Znajduje komentarz w tekście wejściowym, a następnie wywołuje funkcję z dopasowanymi elementami, która w tym przypadku $ this-> choose (...) decyduje, czym zastąpić dopasowanie i zwraca wyniki.
DeweloperChris,

1
Regex to PHP jest dość kiepski ... Wolałbym mieć Regex w stylu Perla lub JavaScript, w którym //jest wbudowany w język.
cdmckay
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.