Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

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 [...]

Autor wpisu: matipl, dodany: 20.09.2010 11:37, tagi: php

php-logoCoraz więcej mam do czynienia z cudzym kodem napisanym w PHP. Zauważyłem, że w wielu miejscach, nie wiem czy przez przypadek czy umyślnie, są tagi zamykające: ?> chociaż być nie powinny.

Tag zamykający powinniśmy używać wyłącznie w sytuacji, gdy poza PHP spodziewamy się czegoś innego, np. są to pliki widoku, w którym zagnieżdżamy wywołania, np.:

<h2><?php echo $page->name ?></h2>
<php echo $page->content ?>
<p>Tagi:
    <ul>
        <?php foreach($tags as $tag) : ??>
            <li><?php echo $tag->name ?></li>
        <?php endforeach ?>
    </ul>
</p>

Dlaczego? Powód jest jeden: błędy. Za tagiem zamykającym może zakraść nam się spacja, znak nowej linii lub inne białe znaki. A to automatycznie powoduje błąd Cannot modify header information – headers already sent, jeśli w kolejnych plikach operujemy na nagłówku strony (header(), setcookie()).

Gdy nasz projekt jest duży, a ktoś zostawi ?> ze spacją lub innym cudem możemy mieć spory problem w szukaniu błędu i stracić sporo czasu. Poza tym interpreter nie musi zastanawiać się co i jak, gdzie kod PHP się zaczyna, a gdzie kończy.

Dlatego dla wszystkich plików, które zawierają tylko PHP zalecam niestosowanie tagu zamykającego ?>, który przez PHP jest niewymagany.

Polecam Wam również zaznajomienie się z Zend Framework Coding Standard.

Autor wpisu: batman, dodany: 16.09.2010 11:28, tagi: internet

IE9-beta_v_rgbMiejsce – Warszawa, klub 35mm, ostatnie piętro Multikina, Złote Tarasy. Czas – 15 września 2010 roku, kilka minut przed godziną 19. Na sali znajduje się 5 stołów oczekujących na przybycie kilkudziesięciu zaproszonych gości – przedstawicieli mediów, blogerów, deweloperów i innych osób zainteresowanych premierą najnowszej przeglądarki Mircosoftu. Sala została przygotowana w białych kolorach z niebieskimi akcentami, mającymi kolorystycznie nawiązywać do loga przeglądarki. Kilkanaście minut po 19, oglądamy w skupieniu przekaz na żywo z San Francisco, na którym prezentowany jest Internet Explorer 9. Po niecałej godzinie głos zabierają (już w Warszawie) przedstawiciele polskiego oddziału Microsoft.

 

Co nowego w wyglądzie?

Ponieważ przeglądarka skierowana jest przede wszystkim do masowego odbiorcy, Microsoft skupił się na zaprezentowaniu wodotrysków, pomijając kwestie stricte techniczne. Nie oznacza to, że Internet Explorer 9 ma się czego wstydzić. Po prostu statystyczny Kowalski nie jest zainteresowany technicznymi szczegółami. Dla niego najważniejsze jest, aby przeglądarka była jak najbardziej przyjazna w użytkowaniu, bezpieczna oraz szybka.

Od strony wizualnej oraz usability, Internet Explorer 9 może śmiało konkurować z pozostałymi przeglądarkami. Największą zmianą dotyczącą wyglądu jest umieszczenie zakładek (kart) obok paska adresu. Szerokość paska adresu można regulować, więc nie ma obawy, iż po otwarciu trzech kart, staną się one nieczytelne.

adressbar-tabs

Kolejną rewolucją jest wykorzystanie dodatkowych możliwości jakie daje nowy interfejs Windows 7. Każdą z kart można przypiąć do paska zadań i korzystać z niej jak z osobnej aplikacji (pinned sites) – podobnie jak ma to miejsce w Google Chrome, z tą różnicą, że każdy ze skrótów oferuje dodatkowe opcje dostępne po kliknięciu na niego prawym przyciskiem myszy. Są to najczęściej wykonywane operacje w danym serwisie (Jump Lists). Dzięki takiemu rozwiązaniu, aplikacje internetowe sprawiają wrażenie zainstalowanych w systemie. W przypadku Facebooka mamy do dyspozycji następującą Jump Listę.

taskbar

W chwili obecnej funkcjonalność taką oferują Facebook, LinkedIn, czy IMDB.

Co więcej, aplikacje internetowe mogą przy pomocy HTML5 urozmaicić swój wygląd poprzez dodanie efektów opartych o nowy standard. Na taki krok zdecydowała się wyszukiwarka Bing, która będzie dostarczać interaktywne tła.

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

Autor wpisu: matipl, dodany: 14.09.2010 15:32, tagi: php

RAD Studio XEKto sądzi z Was, że takiego tworu jak Delphi nie ma już na rynku bardzo się myli. Z języka Delphi nadal się korzysta. W 2009 roku Delphi był na 11. pozycji w najpopularniejszych językach programowania, a na dodatek środowiska programistyczne dla Delphi wciąż się rozwijają.

Firma Embarcadero, która w 2008 roku kupiła pakiet CodeGear od firmy Borland wydała właśnie nowe środowisko RAD m.in. dla języka DelphiRAD Studio XE.

RAD Studio XE oprócz środowisk Delphi XE i C++ Builder XE zawiera także nowe środowisko IDE dla PHPRadPHP™XE oraz nową wersję Delphi Prism™ XE, do programowania .NET oraz Mono. A oto nowości w RAD Studio:

  • SVN
  • W pełni zintegrowane IDE do zespołowego zarządzania kodem źródłowym
  • FinalBuilder Embarcadero Edition
  • Audyty, metryki, formatowanie i generowanie dokumentacji bezpośrednio z linii wiersza poleceń. Automatyzacja procesu tworzenia buildów
  • AQTime Standard
  • Narzędzie do optymalizowania wydajności aplikacji
  • Beyond Compare Text Compare
  • Rozszerzenia w edytorze kodu: wyszukiwanie, formatowanie i nawigowanie po kodzie
  • CodeSite Express
  • Tworzenie wysokiej jakości aplikacji z logowaniem i rozbudowanymi opcjami debugowania

Dodatkowo nowe środowisko posiada nowe komponenty dla Microsoft Windows Azure data types, łatwiejsze wdrażanie „w chmurze” na Amazon EC2 oraz nowe właściwości DataSnap do tworzenia aplikacji wielowarstwowych.

Z okazji premiery nowego środowiska dla Delphi zaplanowano również 3-godzinne konferencje w 5 miastach Polski:

DATA KONFERENCJI MIASTO HOTEL
15 września 2010 Warszawa Gromada Centrum
21 września 2010 Poznań Novotel Malta
22 września 2010 Gdańsk Novotel Marina
28 września 2010 Wrocław Mercure Panorama
29 września 2010 Kraków Orbis Cracovia

Jak widać po coraz większym wsparciu konkurencyjnych języków/rozwiązań firma Embarcadero zdaje sobie sprawę, że lata świetności Delphi ma za sobą. Od siebie dodam, że Delphi bardzo dobrze spełnia swoją rolę jako gruby klient. Nadal szybko tworzy/rozwija się w nim aplikacje i posiada integrację z przeróżnymi stworami (np. FirebirdSQL) przez co nie ma dużego „ciśnienia” aby już działające aplikacje korporacyjne zmieniać na inne technologie.

Autor wpisu: batman, dodany: 13.09.2010 21:15, tagi: javascript

Najpopularniejszym serwisem dostarczającym mapy w Internecie jest Google Maps. Nie oznacza to, że konkurencja pogodziła się z porażką na tym polu. Jedną z ciekawszych alternatyw dla Google Maps jest Bing Maps. Oprócz API dostępnego w języku Javascript programiści mogą korzystać z Silverlighta oraz usług sieciowych. Co więcej, programiści PHP również mają możliwość korzystania z map Bing. Gdyby nie jeden drobny szkopuł, Google mogłoby poważnie obawiać się konkurencji ze strony Bing Maps. Niestety mapy w wydaniu Bing nie są zlokalizowane na polski rynek i wyszukanie adresu lub trasy dojazdu graniczy z cudem.

Zanim zaczniemy

Do tworzenia aplikacji opartych o Bing Maps będzie potrzebny nam specjalny klucz. Możemy go zdobyć na stronie www.bingmapsportal.com, do której zalogujemy się korzystając z konta, np Hotmail. Po założeniu konta uzyskujemy możliwość wygenerowania klucza aplikacji, który później będziemy wykorzystywać. Jako ciekawostkę podam, iż konto utworzone w serwisie dla deweloperów Bing Maps daje nam możliwość śledzenia wykorzystania naszych map oraz dodawania własnych aplikacji do map. Ponieważ oba tematy wykraczają daleko poza ramy dzisiejszego wpisu, nie będę się nimi szerzej zajmował.

Podczas tworzenia aplikacji korzystającej z Bing Maps nie musimy od razu rejestrować klucza. Można to zrobić po zakończeniu prac, dzięki czemu statystyki nie będą zawierały testowych odsłon.

Pierwsza mapa

Podobnie jak w przypadku swojego konkurenta, Bing Maps również wymaga zewnętrznego skryptu, z którego będą ładowane klasy. Adresem tym jest

http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3

gdzie 6.3 oznacza numer wersji, z której chcemy skorzystać.

Kompletny kod, który wyświetli mapę, wygląda następująco.

<html>
	<head>
		<title>Pierwsza mapa</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script type="text/javascript" src=http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3></script>
		<script type="text/javascript">
		var map = null;
		function GetMap()
		{
			map = new VEMap("mapa");
			map.LoadMap();
		}
		</script>
	</head>
	<body onload="GetMap();">
		<div id="mapa" style="position: relative; width: 600px; height: 400px;"></div>
	</body>
</html>

Uruchomienie powyższego kodu spowoduje wyświetlenie domyślnej mapy o rozmiarze zdefiniowanym w atrybucie style.

zobacz przykład

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

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.