Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: batman, dodany: 30.11.2012 17:26, tagi: internet

W poniedziałek rozpoczyna się dwutygodniowa konferencja Międzynarodowego Związku Telekomunikacyjnego (ITU) w Dubaju. Jej przedmiotem będzie głównie projekt zmiany Międzynarodowych Regulacji Telekomunikacyjnych (ITR). W powszechnej opinii panuje przekonanie, że proponowane zmiany to powtórka z ACTA w wersji globalnej. Jak jest naprawdę, (…)

Read the rest of this entry »

Autor wpisu: l3l0, dodany: 29.11.2012 14:03, tagi: php, symfony

Ostatnio bardzo aktywnie zacząłem używać phpspec2 w procesie wytwarzania oprogramowania. Trzeba przyznać, że bardzo pomaga mi to w pracy (szczególnie w połączeniu z behatem) i ostatnio żadko widuje napis “PHPUnit 3.x.x by Sebastian Bergmann.” Niestety żeby nie było za różowo (może i dobrze że nie jest) dokumentacja phpspec2 jest jeszcze dosyć słaba. Ale czego można [...]

Autor wpisu: batman, dodany: 27.11.2012 18:23, tagi: internet

Nie śledzę na bieżąco rynku startupów, jednak ta wiadomość jest na tyle interesująca, podobnie zresztą jak sam projekt, iż warto o tym napisać. Polski startup o nazwie Virtual Recruiter, który wygrał Startup Weekend Trójmiasto, zakwalifikował się do konkursu Global Startup (…)

Read the rest of this entry »

Autor wpisu: Łukasz Socha, dodany: 25.11.2012 21:21, tagi: css

pobierz w .pdf(przeznaczone do wydruku)

Kodując szablon zapewne wiele osób ma problem ze stopką „wiszącą” tuż pod treścią, gdy jest jej za mało, by stopka obsunęła się na dół. Jak ją „przykleić” do dolnej krawędzi niezależnie od ilości treści? Jest na to kilka sposobów…

Metoda Ryana Falta

CSS:

* { 
    margin: 0; 
} 
html, body { 
    height: 100%; 
} 
.wrapper { 
    min-height: 100%; 
    height: auto !important; 
    height: 100%; 
    margin: 0 auto -100px; // taki jak wysokosc stopki
} 
.footer, .push { 
    height: 100px; // taki jak wysokosc stopki
}
.push{
    clear: both;
}

HTML:

<body> 
    <div class="wrapper"> 
        <p>Treść strony www</p> 
        <div class="push"></div> 
    </div> 
    <div class="footer"> 
        <p>Stopka</p> 
    </div> 
</body>

W metodzie tej musimy ustawić dolny margines dla klasy .wrapper o ujemnej wartości wysokości stopki. Ponadto sposób Ryana Falta wymaga dodania pustego kontenera .push o takiej samej wysokości jak stopka. Wadą tego rozwiązania jest zakaz używania górnych i dolnych marginesów – powodują one błędne określenie wysokości strony.

Metoda Steva Hatchera

CSS:

* {
    margin:0;padding:0;
}  
html, body {
    height: 100%;
} 
#wrap {
    min-height: 100%;
} 
#main {
    overflow:auto; 
    padding-bottom: 180px; // taki jak wysokosc stopki
}
#footer {
    position: relative; 
    margin-top: -180px; // taki jak wysokosc stopki
    height: 180px; 
    clear:both;
}
/*Opera Fix*/ 
body:before {/* thanks to Maleika (Kohoutec)*/ 
    content:""; 
    height:100%; 
    float:left; 
    width:0; 
    margin-top:-32767px;/* thank you Erik J - negate effect of float*/ 
}

HTML:

<div id="wrap"> 
    <div id="main"> 
        Treść 
    </div> 
</div> 
<div id="footer"> 
    Stopka 
</div>

Sposób ten jest podobny do metody Ryana Falta. Tutaj także górne i dolne marginesy powodują błędy. Zaletą tego rozwiązania jest to, że nie musimy tworzyć pustych kontenerów.

Poza powyższymi metodami często stosuję min-height dla głównego kontenera z treścią. Może nie jest to zbyt idealne rozwiązanie, ale w większości przypadków wystarczające ;)

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

Autor wpisu: nospor, dodany: 22.11.2012 16:43, tagi: php

Niedawno bawiąc się biblioteką pChart, służącą do rysowania wykresów, natrafiłem na pewien błąd. Rysując wykres kołowy 3d z dużą ilością danych, gdzie kilka z nich miały procentowy udział około 1% okazało się, że wykres jest źle rysowany. Dla mało procentowych wartości ich kawałek wykresu był rysowany jakby z przerwami. Od razu uznałem, że jest to błąd klasy pChart, która nie radzi sobie z małymi danymi i tam właśnie zacząłem szukać błędu. Okazało się jednak inaczej....

Autor wpisu: zleek, dodany: 21.11.2012 07:55, tagi: php, zend_framework

W dniu wczorajszym została opublikowana nowa wersja Zend Framework, tym razem oznaczona numerkiem 2.0.4. Główną zmianą jest wprowadzenie dwóch strategii związanych z widokiem: Zend\View\Strategy\JsonStrategy oraz Zend\View\Strategy\FeedStrategy. Ponadto zostało poprawionych ponad 40 zgłoszonych do poprzedniego wydania bugów. Pełna informacja o najnowszym wydaniu Zend Framework oraz lista poprawek jest dostępna tutaj.

Autor wpisu: Łukasz Socha, dodany: 20.11.2012 20:11, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Na temat wzorców projektowych byłoby póki co tyle ;) Na zakończenie dołączam jeszcze kilka praktycznych przykładów wykorzystania ich w budowie sklepu internetowego.

Przykład 1

Tworzymy sklep internetowy i w specyfikacji mamy określane, że wyświetlana cena ma zależeć od typu klienta (nowy klient, stały klient, hurtownik itp.). Ponadto nie mamy gwarancji, że sposób wyliczania ceny nie zmieni się w przyszłości. Jak odpowiednio zaprogramować ten mechanizm? Najlepiej użyć wzorca strategii. Spójrzmy na przykład:

<?php

interface Price {

    public function count($value);
}

class PriceForNewClient implements Price {

    public function count($value) {
        return 1.20 * $value;
    }

}

class PriceForRegularClient implements Price {

    public function count($value) {
        return 1.15 * $value;
    }

}

class PriceForWholesaler implements Price {

    public function count($value) {
        return 1.10 * $value;
    }

}

class Product {

    private $name;
    private $basicPrice;
    private $strategyPrice;

    public function __construct($name, $basicPrice, $strategy) {
        $this->name=$name;
        $this->basicPrice=$basicPrice;
        $this->strategyPrice = new $strategy();
    }
    public function getPrice() {
        return $this->strategyPrice->count($this->basicPrice);
    }
    public function getName() {
        return $this->name;
    }
    public function setStrategy($strategy) {
        $this->strategyPrice = new $strategy();
    }

}

// testy
$product = new Product("produkt 1", 100, "PriceForNewClient");
echo "Nazwa produktu: ".$product->getName().", cena produktu: ".$product->getPrice()."<br />";
$product->setStrategy("PriceForRegularClient");
echo "Nazwa produktu: ".$product->getName().", cena produktu: ".$product->getPrice()."<br />";
$product->setStrategy("PriceForWholesaler");
echo "Nazwa produktu: ".$product->getName().", cena produktu: ".$product->getPrice()."<br />";

?>

W powyższym przykładzie mamy trzy strategie naliczania ceny zależne od typu klienta. Żeby zmienić sposób wyliczania ceny wystarczy tylko utworzyć nowy obiekt strategii za pomocą setStrategy(). Dzięki zastosowaniu wzorca późniejsze modyfikacje będą znacznie prostsze.

Przykład 2

Kolejnym problemem w naszym sklepie jest sposób generowania różnych widoków. Dla różnego rodzaju porównywarek cenowych listę produktów musimy wygenerować zwykle jako dokument XML, natomiast dla użytkownika potrzebujemy zwykłą stronę HTML. Problem możemy rozwiązać za pomocą fabryki abstrakcyjnej lub metody wytwórczej. Wybierzemy metodę wytwórczą, ponieważ nie potrzebujemy dwóch różnych fabryk. Naszym wymogiem są tylko dwa różne produkty (XML i HTML). Przykład:

<?php

interface IView {

    function render();
}

class HtmlView implements IView {

    function render() {
        // generowanie widoku html
    }

}

class XmlView implements IView {

    function render() {
        // generowanie widoku xml
    }

}

class PdfView implements IView {

    function render() {
        // generowanie widoku pdf
    }

}

class View {

    static function factory($fileName) {
        switch (end(explode('.', $fileName))) {
            case 'html' :
                return new HtmlView();
            case 'xml' :
                return new XmlView();
            case 'pdf' :
                return new PdfView();
            default :
                throw new Exception('nieznany typ pliku');
        }
    }

}

$html = View::factory("strona.html");
var_dump($html);
$xml = View::factory("strona.xml");
var_dump($xml);
$pdf = View::factory("strona.pdf");
var_dump($pdf);

?>

Na podstawie rozszerzenia pliku metoda factory() stworzy obiekt odpowiedniego typu. Tworząc interfejs zapewniamy sobie jednakowe API dla różnych typów dokumentów. Rozwiązanie takie znacznie ułatwia dalszą pracę programisty – nie musi wdawać się w szczegóły techniki generowania danego typu dokumentu, ma do tego zapewnione abstrakcyjne API.

Przykład 3

Nasz sklep internetowy ma być naprawdę rozbudowany ;) . Kolejnym problemem jaki możemy napotkać jest stworzenie API, które ułatwi integrację innym serwisom z naszym sklepem. Takie API na pewno musi zawierać metody do logowania, pobierania produktów i kupowania. Dobrze napisana aplikacja funkcje te ma zawarte w różnych klasach (modelach). A więc powstaje pytanie: jak je scalić? Z pomocą przybywa wzorzec fasady

<?php 
 
class User{
    public function login() {
        echo "Logowanie do systemu\n";
    }
    public function register() {
        echo "Rejestracja\n";
    }
}
 
class Cart{
    public function getItems() {
        echo "Zawartość koszyka\n";
    }
}
 
class Product{
    public function getAll() {
        echo "Lista produktów\n";
    }
     
    public function get($id) {
        echo "Produkt o ID ".$id."\n";
    }
}
 
class API{
    private $user;
    private $cart;
    private $product;
     
    public function __construct() {
        $this->user = new User();
        $this->cart = new Cart();
        $this->product = new Product();
    }
     
    public function login() {
        $this->user->login();
    }
     
    public function register() {
        $this->user->register();
    }
     
    public function getBuyProducts() {
        $this->cart->getItems();
    }
     
    public function getProducts() {
        $this->product->getAll();
    }
     
    public function getProduct($id) {
        $this->product->get($id);
    }
}
 
// testy
$client = new API();
$client->register();
$client->login();
$client->getProducts();
$client->getProduct(5);
$client->getBuyProducts();
 
?>

Chyba nie muszę tego fragmentu tłumaczyć :)

Przykład 4

W projektowanym przez nas sklepie mamy zaimplementowany mechanizm cache’owania. Dodatkowo chcemy informować klientów o dodaniu nowego produktu (np. z wybranej przez nich kategorii). Oczywiście wszystko ma się dziać automatycznie. Jak sobie można z tym poradzić? Używając wzorca obserwatora

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.