Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: batman, dodany: 24.09.2010 18:00, tagi: php

Przeglądając dzisiaj zasoby sieci, natrafiłem na bardzo ciekawy projekt – konsola PHP w przeglądarce. Brzmi nieprawdopodobnie? Ale działa! Cały projekt składa się z jednego formularza, do którego można wprowadzić kod PHP, a następnie go wykonać.

php-console-in-browser

Po co komuś konsola PHP w przeglądarce? Każdy znajdzie inne zastosowanie. Dla mnie będzie to duże ułatwienie podczas testowania niewielkich fragmentów kodu. Zamiast tworzyć skrypt, a następnie odpalać go w wierszu poleceń, uruchomię tą aplikację, a w niej wykonam kod.

Instalacja jest banalnie prosta i sprowadza się do skopiowania zawartości projektu na lokalny serwer. Zainteresowani? Jeśli tak, to odsyłam Was na stronę autora lub na stronę projektu znajdującą się na githubie.

Autor wpisu: Zyx, dodany: 23.09.2010 20:55, tagi: php

W dzisiejszym wpisie zajmiemy się tematyką kontroli uprawnień w aplikacjach, ale od nieco innej strony. Podczas gdy inne artykuły przedstawiają konkretne techniki realizacji list uprawnień i algorytmy ich sprawdzania, ja zajmę się zagadnieniem bagatelizowanym, a nawet wręcz nieistniejącym w świadomości programistów. Spróbuję przedstawić ideę działania oraz sposób implementacji ogólnego mechanizmu kontroli uprawnień, całkowicie oderwanego od takich konkretnych technik i zdolnego obsłużyć każdą z nich.

Autor wpisu: sokzzuka, dodany: 23.09.2010 10:15, tagi: php

Sprawa adnotacji wywołała dość duże poruszenie na liście php.internals. Uformowały się trzy grupy dyskutantów – jedna popierająca adnotacje, druga uważająca, że jest to zupełnie nie potrzebne i komplikuje język i trzecia która stara się znaleźć kompromis. W wyniku dość długiej dyskusji, skrystalizowało się kilka wniosków – po pierwsze adnotacje nie powinny wprowadzać żadnej nowej składni ponad zaznaczenie, że dana część kodu jest adnotacją, czyli coś w rodzaju [kod php] gdzie „[" i "]” oznaczają początek i koniec adnotacji, natomiast jej treść jest poprawnym kodem php. Drugi wniosek jest taki, że grupa nr trzy stwierdziła, że skoro nie można dość do kompromisu w sprawie adnotacji, to może po prostu najlepiej by było wbudować parser phpDoc do mechanizmów refleksji. Trzeci wniosek, jest taki, że pewna część deweloperów nie widzi zastosowania dla adnotacji, co więcej nie wie nawet czym one są i dlatego uważa, że nie należy ich wprowadzać. Z innych ciekawych rzeczy, zauważyłem, że jest grupka deweloperów, którzy mają jakieś doświadczenie z Pythonem i chcieli by zmienić trochę PHP w jego stronę tj. wszystko jest obiektem (klasy, funkcje etc). Wtedy adnotacje mogły by być zastąpione przez Pythonowe dekoratory.

Ogólnie to zauważam dwa albo nawet trzy trendy a właściwie rodzaje ludzi którzy wypowiadają się na liście „internals”. Pierwszy z nich to ludzie, którzy przyszli z środowiska języka C i są raczej dość konserwatywni i nie chcą zbytnio zmieniać formy języka, mają podejście bardziej proceduralne. Drugą grupą są ludzie, którzy mają doświadczenia w Java’ie i C# i próbują przenieść niektóre cechy a nawet całą składnię z tych języków ich podejście to babilońska obiektówka w stylu EJB, czasami nawet dosłownie cytują jakieś dokumenty JSR Java’y. Trzecia grupa, to ludzie pochodzący z języków typu Ruby czy Python oraz języków funkcyjnych. Jest to chyba najmniejsza grupa, ich poglądy uważane są chyba za najbardziej kontrowersyjne wśród pozostałych dwóch grup i raczej niechętnie akceptowane.

Pytaniem na dziś jest więc, po pierwsze, co widzielibyście w przyszłości w PHP – adnotacje, czy wbudowany parser phpDoc, a może żadną z tych rzeczy ? Po drugie, w jakim kierunku powinien ewoluować język – w stronę Python’ową (wszystko jest obiektem, więcej cech języków funkcyjnych) czy może Java/C# ?

Autor wpisu: batman, dodany: 22.09.2010 18:00, tagi: css, javascript

Każda osoba, która chociaż raz musiała wycinać średnio skomplikowany layout, stawała przed dylematem "jak zaokrąglić te przeklęte rogi". Są dwie możliwości - obrazkowa oraz stylowa. W przypadku metody obrazkowej wszystkie zaokrąglenia są zapisywane jako grafika, która następnie jest osadzana w nadmiarowych elementach HTML. Podejście to jest przede wszystkim niezawodne. Każda przeglądarka identycznie wyświetli zamieszczone grafiki. Schody zaczynają się w momencie, gdy zachodzi potrzeba przebudowania wyglądu strony. Zmiana promienia, czy nawet czegoś tak błahego jak kolor obramowania, staje się w tym momencie udręką. Do pracy, w najlepszym wypadku, należy zaprząc jakiś program graficzny, w najgorszym - całego grafika ;), przez co prosta zmiana staje się wyzwaniem na dobrych kilka godzin. Drugie podejście polega na skorzystaniu z dobrodziejstw postępu, czyli z CSS. Kilkanaście znaków w pliku ze stylami może zdziałać cuda.

border-radius: 10px;

Niestety taki zapis zadziała tylko w Operze oraz Google Chrome. Nie oszukujmy się. Ilość osób, która zobaczy, że nasza strona posiada zaokrąglone rogi, jest znikoma. Co z resztą przeglądarek? Ich autorzy wprowadzili prefixy (np znany z Firefoxa -moz). Dzięki temu można wprowadzić "krągłości" w pozostałych przeglądarkach.

-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;

Niestety powyższe rozwiązanie nadal nie spowoduje, że większość odwiedzających naszą stronę nie zobaczy jej tak, jakbyśmy tego chcieli. Pozostaje problem z przeglądarką Internet Explorer. Dopiero wydana niedawno wersja beta oznaczona numerem 9 radzi sobie z czymś tak banalnym. Nie zmienia to jednak faktu, że większość użytkowników ma pecha i korzysta z IE6, 7 lub 8.

I tutaj dochodzimy wreszcie do meritum dzisiejszego wpisu. Niestety nie ma rozwiązania tylko "stylowego". Musimy skorzystać z pomocy Javascript i VML. Nie martwcie się jednak. Nie będziemy nic pisać, skorzystamy po prostu z gotowej biblioteki. Mowa tutaj o DD_roundies, której autorem jest ta sama osoba, która stworzyła jedyny działający fix na obrazki png w przeglądarce IE6. Jedyne dwie czynności jakie mamy do wykonania, to dołączenie pliku z biblioteką do strony oraz wywołanie metody addRule na obiekcie DD_roundies. Metoda przyjmuje trzy parametry. Pierwszym jest selektor CSS, wskazujący na interesujący nas element (wymagany), drugim wartość zaokrąglenia (wymagana). Ostatnim (opcjonalnym) parametrem jest informacja, czy zaokrąglenie ma zostać wykonane tylko w przeglądarce IE (domyślne ustawienie).

Cały kod wygląda następująco:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<style type="text/css">
		#some-id {
			/* przykładowe wartości */
			width: 200px;
			height: 200px;
			border: 1px solid #cccccc;
			
			
			-webkit-border-radius: 10px;
			-moz-border-radius: 10px;
			border-radius: 10px;
		}
		</style>
		<script type="text/javascript" src="DD_roundies_0.0.2a-min.js"></script>
		<script type="text/javascript">
		window.onload = function() {
			DD_roundies.addRule("#some-id", "10px");
		}
		</script>
	</head>
    <body>
		<div id="some-id"></div>
	</body>
</html>

Jeśli chcecie zobaczyć na żywo jak to wygląda, zapraszam do obejrzenia dema.

Na koniec dodam jedynie, że nie jest to "ultimate solution" i na pewno znajdą się sytuacje, w których znacznie lepiej będzie zastosować obrazki. Niemniej we wszystkich moich ostatnich próbach (wprawdzie nieśmiałych i na niewielką skalę), skrypt ten spisał się na medal.

Autor wpisu: JoShiMa, dodany: 22.09.2010 00:52, tagi: skrypty

Pracowicie dłubię w szablonach sklepu, który od jakiegoś czasu dla jednego z moich klientów. Ostatnio na jego życzenie pozmieniałam nieco konstrukcje drzewa kategorii. Dziś klient zadzwonił do mnie i z rozpaczą w głosie oznajmił mi, że jego sklep jest pusty. Po chwili okazało się, że pusty nie jest, ale w opisie kategorii pojawia się nieprawdziwa [...]

Autor wpisu: Vokiel, dodany: 21.09.2010 00:41, tagi: mysql

logo-mysql

Pisząc różnego rodzaju aplikacje zdarza się, że trzeba wprowadzić pewną losowość. Jeśli aplikacja jest oparta na bazie danych, taką losowość najłatwiej wprowadzić pobierając losowe dane. Przerabiając ostatnio stary system, oparty jeszcze o pliki tekstowe postanowiłem przenieść go na bazę danych MySQL. Ponieważ duża część systemu z założenia ma być losowa, zatem koniecznym było napisanie dobrej funkcji wybierającej losowe dane z bazy danych. Wydaje się to banalnie proste, jednak nie tak bardzo.

Najczęstsze rozwiązanie

Posłużę się prawdziwym przykładem, nad którym pracowałem. Mamy tabelę keys, która, dla uproszczenia zawiera 2 kolumny: id | key. Chcemy pobrać jeden losowy rekord. Pierwsza myśl przy próbie napisania takiego zapytania to:

SELECT `id`,`key` FROM `keys`ORDER BY RAND() LIMIT 1;

Szukając rozwiązania w necie najczęściej natkniemy się właśnie na takie rozwiązanie. Nawet przy niewielkiej ilości rekordów nie nazwałbym tego rozwiązania akceptowalnym. Oto co się dzieje przy niewielkiej ilości rekordów:

mysql> SELECT COUNT(`id`) as ILOSC FROM `keys`;
+--------+
| ILOSC  |
+--------+
| 113528 |
+--------+
1 row in set (0.09 sec)
 
mysql> SELECT `id`,`key` FROM `keys` ORDER BY RAND() LIMIT 1;
+--------+-------+
| id     | key   |
+--------+-------+
| 143941 | yahoo
+--------+-------+
1 row in set (0.61 sec)
 
mysql> DESCRIBE SELECT `id`,`key` FROM `keys` ORDER BY RAND() LIMIT 1;
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
|  1 | SIMPLE      | keys  | ALL  | NULL          | NULL | NULL    | NULL | 113739 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+--------+---------------------------------+
1 row in set (0.04 sec)

Więcej niż pół sekundy! Ledwo ponad 100 000 rekordów, a zapytanie trwa 0,6 sekundy. Takie rozwiązanie w żadnym wypadku nie może zostać.

Inne rozwiązania

Aby nie wymyślać koła na nowo przeszukałem czeluście Wujka G. Okazało się, że powyższe rozwiązanie jest najczęściej występującym, niemalże jedynym. Kolejne rozwiązania opierają się już na wykorzystaniu PHP i pobieraniu rekordów poprzez zastosowanie kilku zapytań. Przykładowe rozwiązanie:

$range_result = mysql_query(" SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` ");
$range_row = mysql_fetch_object( $range_result );
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$result = mysql_query(" SELECT * FROM `table` WHERE `id` >= $random LIMIT 0,1 ");

Pobranie tylko jednego losowego rekordu i aż 2 zapytania? Wydaje się, że powinno dać się zrobić to sprawniej. Okazuje się, że autor powyższego kodu pokusił się o jego optymalizację, a nawet użycie pojedynczego zapytania sql.

SELECT `id`,`key` FROM `keys` WHERE id >= (SELECT FLOOR( MAX(`id`) * RAND()) FROM `keys` ) ORDER BY `id` LIMIT 1;

Zapytanie ma za zadanie pobrać rekord o id większym niż zaokrąglony w dół do liczby całkowitej wynik mnożenia maksymalnego id z wylosowaną liczbą z przedziału <0,1>. Niby ma sens, ale co z „optymalnością” zapytania? Gorzej niż z pierwszym. Pomimo, że autor chwali zapytanie, że zajmuje 16% czasu pierwszego, mnie nie satysfakcjonuje. Wystarczy spojrzeć na wyniki działania:

mysql> SELECT `id`,`key` FROM `keys` WHERE id >= (SELECT FLOOR( MAX(`id`) * RAND()) FROM `keys` ) ORDER BY `id` LIMIT 1;
+-----+-------------+
| id  | key         |
+-----+-------------+
| 401 | alfa romeo
+-----+-------------+
1 row in set (12.64 sec)
 
mysql> DESCRIBE SELECT `id`,`key` FROM `keys` WHERE id >= (SELECT FLOOR( MAX(`id`) * RAND()) FROM `keys` ) ORDER BY `id` LIMIT 1;
+----+----------------------+-------+-------+---------------+------------------+---------+------+--------+-------------+
| id | select_type          | table | type  | possible_keys | key              | key_len | ref  | rows   | Extra       |
+----+----------------------+-------+-------+---------------+------------------+---------+------+--------+-------------+
|  1 | PRIMARY              | keys  | index | NULL          | PRIMARY          | 4       | NULL |      1 | Using where |
|  2 | UNCACHEABLE SUBQUERY | keys  | index | NULL          | UniqueSubdomains | 765     | NULL | 113715 | Using index |
+----+----------------------+-------+-------+---------------+------------------+---------+------+--------+-------------+
2 rows in set (0.04 sec)

Satysfakcjonujące rozwiązanie

Powyższe rozwiązanie po małej modyfikacji znacznie przyśpieszyło, na testowanej maszynie dało nie taki zły wynik (select z podaniem id wykonywany jest w 0.05s).

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Kamil, dodany: 20.09.2010 19:08, tagi: framework, javascript

Większość developerów w ostatnich czasach zaczyna coraz częściej korzystać z CDN Google czy Microsoftu celem załadowania jQuery, Prototype czy innego frameworka do JavaScript. Jest w tym mnóstwo korzyści i sam też tak robię. Co jeśli jakimś cudem nie uda się połączyć z zewnętrznym serwerem? Strona pozostanie bez najważniejszej biblioteki, przez co reszta naszych skryptów nie [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.