Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Jacek Skirzyński, dodany: 31.01.2014 23:08, tagi: php

Trochę czasu mineło od ostatniego i w końcu udało mi się znaleźć chwilę na opisanie kolejnych elementów Phinga – filtrów i maperów.

Filtry

Filtry pozwalają na wykonywanie różnych operacji na zawartości plików – na przykład usuwanie komentarzy z kodu. Wywołanie filtrów grupuje się w tagu <filterchain>, przykład poniżej:

	<copy todir="kopia" overwrite="true">
		<fileset dir=".">
			<patternset refid="ogolne" />
		</fileset>
		<filterchain>
			<stripphpcomments />
		</filterchain>
	</copy>

Przykładowy kod definiuje operację kopiowania plików (zdefiniowanych w elemencie <patternset> o ID: „ogolne” do katalogu „kopia”. Oprócz zwykłego kopiowania pliki są przetwarzane przez łańcuch filtrów. W tym wypadku zawierający jeden filtr, który usuwa z plików komentarze PHP.

W momencie pisania tego posta Phing dostarczał 19 wbudowanych filtrów, listę można znaleźć w dokumentacji. Natomiast z popularniejszych filtrów myślę, że należy wymienić:

Z praktycznego punktu widzenia filtry są bardzo przydatne, ale mogą powodować pewne problemy w połączeniu z systemem kontroli wersji – o tym co można poradzić napiszę w dalszej części.

Mapery

Efektem działania filtrów jest zmiana zawartości plików, natomiast mapery działają analogicznie, ale z nazwami plików. W momencie przygotowywania wpisu Phing dostarczał 6 maperów. W moim odczuciu najbardziej przydatne są:

  • GlobMapper – podmiana nazw plików według prostych wzorców;
  • RegexpMapper – to samo, ale z wykorzystaniem wyrażeń regularnych we wzorcach.

Użycie maperów odbywa się w analogiczny sposób jak filtrów – w ramach jakiejś operacji plikowej (przykład zaczerpnięty z oficjalnej dokumentacji):

<copy todir="/tmp">
  <mapper type="glob" from="*.php" to="*.php.bak"/>
  <fileset refid="someid" />
</copy>

Praktyczny przykład użycia

Za dobry przykład użycia Phinga (filtry, mapery) i systemu kontroli wersji uważam generowanie plików konfiguracyjnych projektu.

Idea opiera się na plikach o rozszerzeniu .dist (kwestia umowna). Do systemu kontroli wersji trafiają pliki „szablonowe” (.dist), tak żeby ich struktura mogła być śledzona. Z drugiej strony, aby nie zawierały konkretnych informacji (np. dostęp do bazy danych). W tych plikach zamiast wartości pojawiają się Phingowe odwołania do zmiennych. Utworzenie działającego pliku konfiguracyjnego polega na:

  1. skopiowaniu pliku
  2. zmianie rozszerzenia z .php.dist na .php
  3. podstawieniu wartości w miejsce wywołań zmiennych

Plik config/Config.php.dist:

<?php

class Config
{
	const DB_HOST = '${config.db.host}';
	const DB_NAME = '${config.db.name}';
	const DB_USER = '${config.db.user}';
	const DB_PASSWORD = '${config.db.password}';
}

Plik srodowisko.properties:

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

Autor wpisu: zleek, dodany: 27.01.2014 14:12, tagi: php, zend_framework

Pracując przy ostatnim projekcie bazującym na Zend Framework 2 napotkałem dziwny błąd. Mianowicie dla pól formularza, które miały atrybut required miały ustawiony na true, nie mogłem ustawić własnego komunikatu błędu. Pomimo tego, że walidator dla tego pola ustawiony w InputFilter, wyglądał na prawidłowy, wyświetlana była domyślna wartość komunikatu błędu. Okazało się, że problem nie leżał […]

Autor wpisu: Łukasz Socha, dodany: 23.01.2014 19:09, tagi: php

W tym wpisie pokażę jak łatwo można nanosić obiekty wraz z ich opisami na mapę wykorzystując API Google Maps. Jest to trzecia część z cyklu o geolokalizacji i Googlee maps.

Jeżeli drogi czytelniku nie czytałeś poprzednich części cyklu zachęcam Cię do przeczytania pierwszego wpisu. Wiedza tam zawarta jest niezbędna do zrozumienia poniższego kodu.

Gotowy? No to przejdźmy do kodu i jego analizy :)

<!DOCTYPE html>
<html>
    <head>
        <style>
            html, body, #map_canvas {
                height: 100%;
                margin: 0px;
                padding: 0px;
            }
            #map-container{
                height: 100%;
            }
        </style>
        <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&amp;libraries=places"></script>
        <script>
            /**
             * 
             * @type @exp;google@pro;maps@call;Map Obiekt mapy
             */
            var map;
            /**
             * 
             * @type Array Tablica markerow
             */
            var marker = new Array();
            /**
             * 
             * @type Array Tablica chmurek z opisami dla markerow
             */
            var infowindow = new Array();

            /**
             * Tworzy obiekt mapy z podstawowymi ustawieniami
             * @returns void
             */
            function initialize() {
                var myLatlng = new google.maps.LatLng(52.24125614966341, 20.9619140625);
                var mapOptions = {
                    zoom: 7,
                    center: myLatlng
                };
                map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
            addMarker(new google.maps.LatLng(52.24125614966341, 20.9619140625), 'Warszawa', 'Stolica Polski');
            addMarker(new google.maps.LatLng(50.0647793, 19.9475100), 'Kraków', 'Piękna starówka :)');
            addMarker(new google.maps.LatLng(51.1462584, 21.9684219), 'Opole Lubelskie', 'A tu mieszkam i pracuję...');
            }

            /**
             * Dodaje marker do mapy
             * @param Latlng latlng obiekt ze wspolrzednymi geograficznymi
             * @param string name Nazwa markera
             * @param string description Opis markera do chmurki
             * @returns void
             */
            function addMarker(latlng, name, description) {
                console.log("Wspolrzedne: " + latlng.lat() + ' ' + latlng.lng());
                marker.push(new google.maps.Marker({
                    position: latlng,
                    map: map,
                    title: name
                }));
                infowindow.push(new google.maps.InfoWindow({
                    content: description
                }));
                // wyswietla dymki po kliknieciu na marker
                google.maps.event.addListener(marker[infowindow.length - 1], 'click', (function(i) {
                    return function() {
                        infowindow[i].open(map, marker[i]);
                    }
                })(infowindow.length - 1));
            }

            google.maps.event.addDomListener(window, 'load', initialize);
        </script>
    </head>
    <body>
        <div id="map-container">
            <div id="map_canvas"></div>
        </div>
    </body>
</html>

Najbardziej interesującym fragmentem kodu jest dla nas funkcja addMarker(). Funkcja ta posiada 3 argumenty: obiekt latlng (zawierający współrzędne geograficzne), nazwę oraz opis pozycji.

W linii 57 dodaję do tablicy nowy obiekt markera – jako jego parametry ustawiam pozycję, nazwę oraz podaję obiekt mapy, na której ma być narysowany. W kolejnej linii tworzę obiekt InfoWindow, który zawiera opis pozycji. Opis ten może zawierać kod HTML, dzięki czemu mamy spore pole manewru :).

W linii 66 dla każdego elementu tablicy z markerami dodaję listener, który po kliknięciu na marker otwiera okno z opisem danej pozycji.

W funkcji initialize() tworzę 3 przykładowe markery. Dlaczego akurat tam? Przed jakąkolwiek modyfikacją musi być stworzony obiekt mapy.

Jak to wygląda w praktyce możesz zobaczyć pod tym linkiem.

Autor wpisu: batman, dodany: 18.01.2014 11:37, tagi: internet

Narzędzi do zapisywania ulubionych stron jest mnóstwo – od najzwyklejszych zakładek w przeglądarce, na dedykowanych aplikacjach i rozszerzeniach kończąc. Wszystkie te rozwiązania mają jedną wspólną wadę – trudno zsynchronizować zapisane strony na każdym urządzeniu. Problemem jest konieczność instalacji aplikacji lub (…)

Read the rest of this entry »

Autor wpisu: Śpiechu, dodany: 12.01.2014 20:46, tagi: php

I’ve always looked for a rational explanation of using traits in PHP and I think I’ve found one. Let’s say we have a bunch of status codes which are set using constants. To remind: constants can also be set in interfaces (notice that constant interface pattern is considered as a bad practice).

We are writing an utils library and simply don’t trust users :-) It means we need to check if status codes set on object are valid. One way is to keep status codes as a range from number to number. Validating is easy in that case. We’re simply check if status is in range. This is obviously not common. In that case we can use reflection to list all class constants. And what if we have unrelated hierarchies of objects? We must duplicate some code. It’s against DRY principle. Trait to the rescue!

Take look at my rich documented gist and see how it works at the bottom of listing. Code is licensed under MIT License, so grab it and use it.

Autor wpisu: matiit, dodany: 01.01.2014 18:21, tagi: php

Świat wolny od miliona require i include

PHP od wersji 5.3.0, a więc już od jakiegoś czasu wspiera przestrzenie nazw, czyli w oryginale namespace. Mówi się, że lepiej późno niż wcale, z tego powodu nie będę się rozwodził nad tym, że od wielu lat PHP było w tyle, zachęcało do budowania aplikacji w brzydkim stylu – trudno, od jakiegoś czasu wszystko idzie w lepszą stronę.

Nie trudno pewnie sobie wam przypomnieć sytuację, w której include był używany w co drugim pliku, nikt nie wiedział co się skąd bierze i tak dalej. Dzisiaj pokażę jak stworzyć małą aplikację w PHP korzystając z dobrodziejstw PSR, namespace, composer. Jak prosto jest używać zewnętrznych bibliotek i jak nie pogubić się we wczytywaniu masy plików w miejscach do tego nieprzeznaczonych.

Wyobraźmy sobie, że piszemy jakiś parser zbierający informacje. Mamy do wyciągnięcia dane z jakiejś strony – parsowanie HTML i zapisanie tego do bazy danych.

Zewnętrzne biblioteki

W celu ułatwienia sobie pracy, postanawiamy skorzystać z zewnętrznej biblioteki tworzenia zapytań HTTP. Wybieramy na przykład Guzzle.

Zacznijmy od zainstalowania composera. Proces instalacji jest banalnie prosty, więc nie ma sensu go opisywać. Daję tylko odnośnik: http://getcomposer.org/doc/00-intro.md#installation-nix

composer.json

Przejdźmy do stworzenia pliku, który będzie opisywał dla composera nasz projekt:

{
  "name": "matiit/justForExample",
  "description": "Example for blogpost",
  "license": "MIT",
  "require": {
    "guzzle/guzzle": "3.8.*@dev"
  }
}

Oraz wykonajmy polecenie composer install w katalogu z naszym projektem (lub php composer.phar install  - w zależności od tego jak zaintstalowaliśmy composera).

Dostaniemy fajną strukturę:


.
├── composer.json
├── composer.lock
└── vendor
 ├── autoload.php
 ├── composer
 │   ├── autoload_classmap.php
 │   ├── autoload_namespaces.php
 │   ├── autoload_real.php
 │   ├── ClassLoader.php
 │   └── installed.json
 ├── guzzle
 │   └── guzzle
 │   ├── build.xml

I tak dalej wgłąb guzzle/

Mamy więc już zainstalowaną i prawie gotową do użycia bibliotekę guzzle. Proste, tak? Tak.

Teraz potrzebujemy „naszego kodu”. Warto utworzyć folder o nazwie src oraz pozmieniać trochę w composer.json, tak, aby korzystać z dobrodziejstw PSR-0.

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.