Prosta księga gości w PHP z wykorzystaniem PDO i SQLite

Artykuł dodany: 19 stycznia 2016. Ostatnia modyfikacja: 08 lutego 2017.

Stopień trudności (1 - dla początkujących, 5 - dla ekspertów): 1

Tematem dzisiejszego artykułu będzie bardzo prosta księga gości, napisana z wykorzystaniem języka PHP i bazy danych SQLite. Poznamy czym są wyjątki, w jaki sposób pobierać i wstawiać dane za pomocą PDO, jak zabezpieczać dane pochodzące od użytkownika przy użyciu funkcji filtrujących. Założeniem będzie, aby księgę można osadzić na dowolnej stronie internetowej, dołączając jej jeden plik. Struktura plików dla całego projektu będzie miała postać:

|-guestbook.db   - plik bazy danych
|-guestbook.php  - logika, operacje na bazie
|-guestbook.html - formularz dodawania nowych wpisów

Zakładam Czytelniku że znasz choćby podstawy języka SQL oraz wiesz czym jest HTML. Wszystkie dane zapisywane będą jako UTF-8. Zaczynajmy.

Przygotowanie bazy danych SQLite

Większość przykładów księgi gości znalezionych w sieci operuje na zwykłych plikach tekstowych. Chociaż są one łatwe w odczycie i stosunkowo proste do wykonania, mogą sprawić kilka problemów np. przy jednoczesnym dostępie do tego samego pliku może wystąpić blokada, wpisy mogą zostać nadpisane. Równocześnie, nie ma praktycznie hostingu, który nie oferowałby dostępu do bazy danych SQLite. Nie wymaga ona żadnej zaawansowanej konfiguracji, jest bardzo szybka i co najważniejsze, oferuje standard języka SQL do przeprowadzania operacji. Bazę możemy utworzyć w dowolnym programie a nawet wtyczce do Firefoksa.

Nasza baza danych będzie wymagała kilku pól, które najlepiej pokazać na przykładzie struktury danych:

CREATE TABLE "guestbook"(
	"id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,
	"add_date" DateTime NOT NULL DEFAULT (datetime('now','localtime')),
	"username" Text NOT NULL,
	"email" Text NOT NULL,
	"comment" Text NOT NULL
);

Kluczem głównym jest kolumna `id`. Dzięki opcji AUTOINCREMENT każdy nowy rekord, wstawiony za pomocą polecenia INSERT, zwiększy nam licznik o 1. Następnie mamy `add_date` – pole typu DateTime czyli przechowujące dane w postaci np.: 2016-01-19 19:29:03. Konstrukcja DEFAULT datetime(‘now’,‘localtime’) powoduje, iż wstawienie nowego rekordu automatycznie uzupełni pole o bieżącą datę. Będziemy mogli zatem pominąć je przy dodawaniu nowych rekordów. Pozostałe pola – `username`, `email`, `comment` – są typu tekstowego. Wszystkie pola są wymagane – nie mogą zawierać w sobie wartości NULL.
Gotową bazę danych będzie można pobrać w plikach na końcu artykułu.

Przygotowanie formularza HTML

Gdy mamy już gotową strukturę bazy danych możemy przejść do stworzenia formularza. Będzie on zawarty w oddzielnym pliku HTML, wczytywanym przez główny skrypt PHP.

guestbook.html

<form action="" method="POST" class="gb_form">
    <fieldset>
        <legend>Nowy wpis w księdze gości</legend>
        <div>
            <label for="gb_username">Nick / Nazwa użytkownika</label>
            <input id="gb_username" type="text" name="gb_username" required />
        </div>
        <div>
            <label for="gb_email">Adres e-mail</label>
            <input id="gb_email" type="email" name="gb_email" required />
        </div>
        <div>
            <label for="gb_comment">Komentarz</label>
            <textarea name="gb_comment" id="gb_comment" cols="30" rows="10" required></textarea>
        </div>
    </fieldset>
    <input type="submit" name="gb_save" value="Zapisz komentarz" />
</form>

Chcemy aby istniała możliwość osadzenia formularza na dowolnej stronie internetowej, stąd dla rozróżnienia, wszystkie elementy oznaczymy prefiksem `gb_`. Zgodnie z wcześniejszymi założeniami, pola `email`, `username` oraz `comment` są wymagane, dlatego będą posiadały atrybut `required`. Nie zwolni to nas oczywiście ze sprawdzenia po stronie PHP czy faktycznie wartość danego pola została przesłana. W artykule nie będę zajmował się stylowaniem za pomocą CSS – zostawiam to już Wam.

Wyświetlenie formularza na stronie

We wcześniejszym kroku przeniosłem formularz do zewnętrznego pliku z kilku powodów. Po pierwsze, nie ma większego sensu mieszać kodu HTML z PHP. Można oczywiście osadzić go za pomocą echo czy heredoc ale spowoduje to wolniejszą pracę parsera oraz problemy z łączeniem ciągów. Po drugie, dobry edytor umożliwi wygenerowanie całej struktury formularza prawie automatycznie (np. dzięki emmet.io). Podpowie też składnię HTML. I w końcu po trzecie, jeżeli korzystamy na stronie z systemów szablonów będzie można łatwo przepisać kod tak, aby był z nim zgodny. Biorąc to pod uwagę wyświetlenie formularza sprowadzi się do jego dołączenia poprzez require:

guestbook.php

<?php

require 'guestbook.html';

Dodawanie nowych wpisów

Pora zająć się logiką naszej mini aplikacji. Wiadomo już że podzielona będzie na dodawanie nowych wpisów oraz listowanie istniejących w bazie. Dodawanie powinno być wykonane dla metody POST, wyświetlanie natomiast dla GET. Jak w PHP odczytać te wartości? Język PHP zawiera kilka predefiniowanych zmiennych globalnych, dostępnych zazwyczaj w postaci tablicy. Interesująca jest zmienna $_SERVER w której znajdziemy bardzo użyteczne dane dotyczące informacji środowiskowych. Polecam jej wyświetlenie za pomocą polecenia:

var_dump($_SERVER);

Wśród wyświetlonych kluczy znajduje się indeks `REQUEST_METHOD` i to dzięki niemu wiemy, jaka metoda żądania została wykorzystana do udzielenia dostępu do strony. Możemy teraz zmodyfikować nasz plik `guestbook.php` o następujące linie:

<?php
// odczytujemy metodę dostępu do strony
$method = $_SERVER['REQUEST_METHOD'];

// POST
if ('POST' === $method && isset($_POST['gb_save'])) {
    // kod wpisujemy tutaj
} elseif ('GET' === $method) { // GET
}
require 'guestbook.html';

Dodatkowo dla metody POST sprawdzamy, czy ustawiona jest zmienna $_POST[‘gb_save’] czyli przycisk `submit` formularza. Ma to na celu jednoznaczne zidentyfikowanie formularza gdyby było ich kilka na naszej stronie docelowej, a każdy wysyłałby dane metodą POST. Możemy też skonfigurować od razu ciąg DSN dla sterownika PDO. Nie jest on szczególnie skomplikowany dla bazy SQLite – zawiera tylko nazwę pliku:

<?php
// DSN dla PDO
$dsn = 'sqlite:guestbook.db';
// odczytujemy metodę dostępu do strony
$method = $_SERVER['REQUEST_METHOD'];
...

W artykule dotyczącym PDO opisałem podstawowe założenia oraz polecenia. Zalecam lekturę jeżeli nie miałeś Czytelniku wcześniej z nim kontaktu. Pamiętaj aby do łączenia z bazą nie używać funkcji mysql_*() gdyż straciły już jakiekolwiek wsparcie a w PHP7 zostały całkowicie usunięte. Co zmienia się w stosunku do baz takich jak MySQL czy PostgreSQL to polecenie ustawiające metodę porównywania znaków. Zamiast SET NAMES, SQLite wykorzystuje PRAGMA:

$dbh = new PDO($dsn);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->exec('PRAGMA encoding = "UTF-8";');

Linia setAttribute ustawia, że w przypadku wystąpienia błędu ma zostać rzucony wyjątek. W największym uproszczeniu wyjątki to zaawansowane, hierarchiczne struktury if/else. Możemy je zagnieżdżać wielokrotnie w sobie. Wyjątki są określonego typu – dla PDO jest to PDOException. Oznacza to że blok catch może złapać ten konkretny wyjątek a resztę pominąć. Na górze struktury wyjątków znajduje się `Exception` po którym inne wyjątki dziedziczą. Polecam przestudiowanie dokumentacji gdyż wyjątki są jedną z podstawowych struktur dobrze napisanej aplikacji.

Kolejną kwestią jest filtrowanie danych. Należy pamiętać aby zawsze bezwzględnie zabezpieczać dane pochodzące od użytkownika. Wszystkie dane wprowadzane na stronie, nagłówki, ciasteczka czy sesje można złamać i wstrzyknąć niebezpieczny kod. Dobrze stosowane PDO, powinno chronić przed podstawowymi atakami SQL Injection. Dobrze, oznacza przygotowywanie zapytań przez metodę prepare() oraz bindowanie parametrów. Inne metody jak `query()` czy `exec()` nie chronią zapytań. Na tym etapie należy sobie też postawić pytanie, czy dane z zewnątrz powinny być przefiltrowane przed umieszczeniem w bazie (dotyczy np. komentarza i możliwych tagów HTML), czy przechowywane w formie nienaruszonej. Zaawansowani programiści wybiorą zapewne opcję drugą – dzięki temu będą mieć zawsze komentarz w formie oryginalnej. My jednak, ze względu na możliwość wykonania ataku XSS przy wyświetlaniu danych, postawimy na usunięcie niebezpiecznych elementów przed ich dodaniem do bazy. Można to zrobić np. wyrażeniami regularnymi, ale wygodniej będzie skorzystać z wbudowanych funkcji filter_var(), filter_input_array() i pochodnych.

if ('POST' === $method && isset($_POST['gb_save'])) {
    $args = array(
        // Sprawdzamy poprawność adresu email za pomocą wbudowanego walidatora
        'gb_email' => array(
            'filter' => FILTER_VALIDATE_EMAIL
        ),
        // nazwa komentującego musi zawierać minimum 10 znaków
        // po sprawdzeniu długości zwracamy wyczyszczone dane
        'gb_username' => array(
            'filter'  => FILTER_CALLBACK,
            'options' => function($username) {
                return (mb_strlen($username) < 5) ? false : filter_var($username, FILTER_SANITIZE_STRING);
            }
        ),
        'gb_comment' => array(
            'filter'  => FILTER_CALLBACK,
            'options' => function($comment) {
                return (mb_strlen($comment) < 10) ? false : filter_var($comment, FILTER_SANITIZE_STRING);
            }
        )
    );
    $filter = filter_input_array(INPUT_POST, $args);
    var_dump($filter);
}

Filter_input_array w naszym przykładzie, pobiera wszystkie dane z tablicy POST i aplikuje do niej filtry. Adres email sprawdzany jest za pomocą wbudowanego walidatora, do dwóch pozostałych pól aplikujemy nasz własny filtr (FILTER_CALLBACK) będący funkcją anonimową. Nazwa użytkownika musi mieć odpowiednio minimum 5 znaków, komentarz minimum 10. Po poprawnej walidacji dane czyszczone są przy użyciu FILTER_SANITIZE_STRING, który działa m.in. jak funkcja htmlspecialchars(). W przypadku niepoprawnej walidacji zwracane jest `false`. Fakt ten możemy w bardzo ciekawy sposób wykorzystać. Aplikując do zmiennej $filter funkcję array_filter() bez parametrów, otrzymamy tablicę samych poprawnych wartości.

var_dump(array_filter($filter));

Zadanie: Wyświetlić błędy dla niepoprawnych pól, wstrzymać dalsze wykonywanie skryptu (dodawanie danych do bazy) jeżeli dane są nieprawidłowe.

Pokażę teraz jak wstawić dane do bazy, ale przerwanie skryptu zostawiam jako zadanie domowe. Piszcie w komentarzach jak sobie z nim poradziliście.

Zapytanie to prosty INSERT wstawiający wartości pobrane z przefiltrowanej tablicy:

$sql = 'INSERT INTO guestbook(email, username, comment) VALUES(:email, :username, :comment)';
$sth = $dbh->prepare($sql);

Jak wspomniałem wcześniej, data dodania komentarza oraz id komentarza to wartości generowane automatycznie, zatem pomijamy je na liście pól do wstawienia. Pozostałe wartości zostały wcześniej odfiltrowane i sprawdzone. Dostępne są pod zmienną $filter:

$sth->bindParam(':email', $filter['gb_email']);
$sth->bindParam(':username', $filter['gb_username']);
$sth->bindParam(':comment', $filter['gb_comment']);
$sth->execute();

Musimy też zadbać o to, aby w przypadku wystąpienia błędu w operacjach na bazie danych, został on wypisany na ekran (złapać wyjątek). Całość kodu dla metody POST prezentuje się następująco:

if ('POST' === $method && isset($_POST['gb_save'])) {
    $args = array(
        'gb_email' => array(
            'filter' => FILTER_VALIDATE_EMAIL
        ),
        'gb_username' => array(
            'filter'  => FILTER_CALLBACK,
            'options' => function($username) {
                return (mb_strlen($username) < 5) ? false : filter_var($username, FILTER_SANITIZE_STRING);
            }
        ),
        'gb_comment' => array(
            'filter'  => FILTER_CALLBACK,
            'options' => function($comment) {
                return (mb_strlen($comment) < 10) ? false : filter_var($comment, FILTER_SANITIZE_STRING);
            }
        )
    );
    $filter = filter_input_array(INPUT_POST, $args);
    var_dump(array_filter($filter));
    // TODO: przerwać działanie skryptu jeżeli część pól została niepoprawnie wypełniona

    try {
        $dbh = new PDO($dsn);
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $dbh->exec('PRAGMA encoding = "UTF-8";');

        $sql = 'INSERT INTO guestbook(email, username, comment) VALUES(:email, :username, :comment)';
        $sth = $dbh->prepare($sql);
        $sth->bindParam(':email', $filter['gb_email']);
        $sth->bindParam(':username', $filter['gb_username']);
        $sth->bindParam(':comment', $filter['gb_comment']);
        $sth->execute();
    } catch (PDOException $e) {
        echo 'Klasa PDO zwróciła wyjątek: ' . $e->getMessage();
    }
}

Wyświetlanie wpisów z księgi gości

Samo wyświetlenie zapisanych wcześniej wpisów jest bardzo proste. Polega na pobraniu danych z bazy i wygenerowaniu tabeli (lub innej odpowiedniej struktury HTML).

elseif ('GET' === $method) {
    try {
        $dbh = new PDO($dsn);
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $dbh->exec('PRAGMA encoding = "UTF-8";');

        // Pobieramy wszystkie wpisy
        $sql = 'SELECT * FROM guestbook';
        $result = $dbh->query($sql);
        if (false === $result) {
            echo 'Brak wpisów w księdze gości';
        } else {
            echo '<table class="gb_table">';
            echo '<thead><tr><th>E-mail</th><th>Nazwa użytkownika</th><th>Komentarz</th></tr></thead><tbody>';
            foreach ($result as $row) {
                echo '<tr>';
                echo '<td>', $row['email'], '</td>';
                echo '<td>', $row['username'], '</td>';
                echo '<td>', nl2br($row['comment']), '</td>';
                echo '</tr>';
            }
            echo '</tbody></table>';
        }
    } catch (PDOException $e) {
        echo 'Klasa PDO zwróciła wyjątek: ' . $e->getMessage();
    }
}

Można oczywiście znowu przerzucić HTML do zewnętrznego pliku (albo wykorzystać system szablonów który idealnie nadaje się do generowania tego typu danych), jednak dla ułatwienia postanowiłem generować kod “w locie”. W przypadku komentarza, zamieniamy jeszcze wszystkie znaki nowej linii na element `br`. Metoda query() zwraca `false` w przypadku niepowodzenia, co wykorzystaliśmy do sprawdzenia czy jakieś wpisy zostały pobrane. Dbamy też o to, by przechwycić wszystkie możliwe wyjątki. Widać że część kodu odpowiedzialnego za połączenie z bazą jest powtórzona. Można go oczywiście przenieść wyżej i jest to drugie zadanie dla Was. Ponieważ i tak potrzebujemy w obu przypadkach nawiązać połączenie, nie musimy się martwić o “lazy loading”.

Podsumowanie

Praca na bazie SQLite z wykorzystaniem PDO jest naprawdę przyjemna. W wielu miejscach może z powodzeniem zastąpić zwykłe pliki tekstowe. Aż szkoda że tak rzadko mniej doświadczeni użytkownicy z niej korzystają. Filtrowanie danych za pomocą wbudowanych w PHP funkcji nie jest jeszcze doskonałe, ale w przypadku mniej zaawansowanego kodu sprawdza się wyśmienicie. Myślę że kod przedstawiony w artykule można z powodzeniem wykorzystać do w pełni działającego projektu. Jeżeli dołożyć do niego jeszcze edycję zamieszczonych komentarzy będzie się sprawdzał znakomicie.

Pliki przestawione w artykule można pobrać z serwisu Github.

Potrzebujesz gotowej księgi gości? Teraz możesz zakupić w pełni funkcjonalny skrypt z panelem administracyjnym.

Komentarze

  • Всем известно, что онлайн-знакомства почти всегда они не дают требуемого результата, по этой причине здесь мы образовали этот сайт с одной целью: сделать онлайн-знакомства без оплаты, легкими и увлекательными ради абсолютно всех. Абсолютно не можете разыскать свою другую половинку? <br /> Но есть неплохая альтернатива – ресурсы знакомств без регистрации в России. Вы можете без проблем в любое комфортное для вас лично время отыскать родственную душу без труда на данном спец сайте в режиме онлайн, где множество современных людей повседневно разговаривают друг с другом.Всего-лишь пару минуток приятного обычного человеческого общения позволяют до неузнаваемости изменить вашу сегодняшнюю повседневная жизнь, в ней, наконец, появится любовь и счастье. <br /> Не важно, где лично вы находитесь, в России либо в ином государстве, у вас есть возможность завести знакомство с мужчиной либо женщиной из Нашего государства. <br /> Для этого не требуется проходить процедуру регистрации на сервисе, чтобы получить доступ к базе данных.

    Всем известно, что он-лайн-знакомства довольно часто они не предоставляют желанного результата, именно поэтому мы организовали этот сайт с единственной целью: сделать он-лайн-знакомства бесплатными, легкими и увлекательными в интересах всех без исключения. Никак не можете отыскать свою другую половинку?

    Теперь имеется отличная альтернатива – онлайн-ресурсы знакомств не регистрируясь в Российской федерации. Возможно в удобное для вас время суток увидеть родственную душу легко на нашем специализированном веб-сайте, где сотни и сотни современных людей ежедневно разговаривают друг с другом.Всего-лишь несколько минут милого общения смогут до неузнаваемости изменить вашу реальность, в ней, наконец, возникнет страсть и наслаждение. <br /> Вне зависимости от того, где лично вы живете, в России или в ином государстве, у вас имеется возможность знакомиться с мужчиной или женщиной из Нашего государства. <br /> Для этого не требуется выполняться процедуру регистрации на веб-сайте, чтобы получить доступ к базе данных. <br /> Все записи и знаки заинтересованности в виде подарков останутся конфиденциальными. <br /> Если у вас великое стремление встретить вторую половинку как можно раньше, оформите ВИП страницу, на котором имеется услуги индивидуальных задач. Тем, кто не любит спешки в поиске близкого человека, может радоваться комфортным разговором. Подарите для себя возможность быть счастливым.

    Сайт знакомств Белгород : <a href=https://simpotka.ru>Сайт знакомств Кемерово</a>

  • All services given by our firm in New york city, performed both on a one-off and on a lasting basis. Any additional can be chosen by consumers only separately. In the job of a cleaning firm in New York, the best quality products. Many thanks to consistent specialist growth, equipment and cleaning methods are constantly being improved. For that reason, the result of our work can satisfy the needs of even one of the most requiring clients. <br /> Costs you can figure out from the catalog. Do not lose your time on deceitful entertainers, call the professionals!

    Express Solution

    The business uses home cleaning services, including making use of commercial mountaineering, as well as other assistance, such as cleansing leather furniture. Here you can order the cleaning of the apartment all at once or, claim, its components, the kids’s area after the renovation, or the living room after a noisy celebration. The benefit of cleaning is expert take care of the tidiness, comfort, health and wellness, time and state of mind of residents or employees in a specific space. The best aide in restoring order as well as sanitation is a specific specialist solution firm. Professionalism and reliability, effort, hard work of personnel, making use of premium cleaning agents create an ambience of best sanitation.

    House cleaning maids Manhattan – <a href=https://maidsmanhattan.club>maids new jersey</a>

  • Наша корпорация делает свою работу по восстановлению и очистки водопроводов новым методом гидродинамической очистки на новейшем оборудовании. Использование указанного способа дает гарантию восстановления функций стальных труб к начальному уровню, уменьшаются расходы электроэнергии на 15процентов, увеличивается установленный срок использования стальных труб на 20 лет до капремонта, увеличиваются интервалы между профилактическим сервисом. <br /> Выполняем абсолютно любые работы, в частности: <br /> Аварийный ремонт наружного водопровода-восстановление рабочего состояния в течение 24 часов.

    Из каких соображений выбирают нашу фирму? <br /> Гигантский стаж работы – более сотни восстановленных очистных сооружений в России и за её пределами, присутствие всех без исключения лицензий и разрешений на производство ремонтно-строительных и технологических задач, создание и проектирование экологического, безопасного, энергосохраняющего, очень эфективного оснащения, гарантийное обслуживание, высокопрофессиональный и ответственный коллектив.

    Обсадка труб скважин – <a href=https://akvasos.ru/>Геофизическое исследование скважин на воду</a>

  • Наша производственная компания выполняет услуги по восстановлению и очистки водопроводов новым способом гидродинамической очистки на новом парке оборудования. Использование данного способа дает гарантию возобновления функций стальных труб к начальному уровню, убавляются затраты электричества на 15%, увеличивается промежуток времени работы стальных труб на 20 лет до капремонта, повышаются промежутки между проф. сервисом. <br /> Фирма организует любые работы, например: <br /> Аварийный ремонт канализации-восстановление внешней системы канализации в течение 2 часов.

    Почему выбирают данную специализированную компанию? <br /> Громадный опыт работы – более сотни восстановленных очистительных сооружений в Нашем государстве и за её пределами, наличие всех лицензий и разрешений на осуществление реставрационных и технических работ, создание и проектирование экологического, безопасного, энергосохраняющего, очень эфективного оборудования, послегарантийное техобслуживание, безупречный и ответственный коллектив.

    Чистка фильтров скважин : <a href=https://synergy90.ru>Геофизическое исследование скважин на воду</a>

  • Cleaning work in the spring is an opportunity implement cleaning the house, on the street, at home. <br /> Streets, courtyards, gardens, squares and urban square need not only clear from dirt accumulated in snow Cleaning work in the spring is an opportunity implement cleaning work, rooms and also in my apartment. <br /> Streets, courtyards, parks, squares and other urban areas need not only clear from the dirt that formed during the winter, take out the garbage, but also prepare for the summer period. For this purpose it is necessary to restore damaged sidewalks and curbs, repair broken small architectural forms sculptures, flowerpots,artificial reservoirs,benches, fences, and so on, refresh fences, painting and many other things. <br /> We hold spring cleaning cottages in areas , but with pleasure we can tidy up . Specialists production company Graniteville can hold spring cleaning 2018.

    We hold spring general cleaning in areas , we can put in order private households and suburban plots . <br /> Our specialists Plum Beach do spring garden cleaning. <br /> Our General Partnership cleaning organization Lower East Side DIXIE, is engaged spring cleaning plot in Manhattanville under the direction of MATILDA.

    The maid Bococa : <a href=https://springcleaning.pro>Spring cleaning</a>

  • Приветствую вас! команда СЕО для раскрутки и продвижения интернет-сайтов в поисковых серверах и дополнительно соц сетях. И меня зовут Антон, я учредитель большой группы линкбилдеров, маркетологов, профессионалов, рерайтеров/копирайтеров, оптимизаторов, link builders, разработчиков, специалистов, копирайтеров. Мы – команда профессиональных фрилансеров. Наши специалисты могут помочь вашему любому веб-сайту подняться в ТОП 15 в выдаче поиска различной системе. Для вас мы предлагаем лучшую раскрутку веб-сайтов в поисковых серверах! Каждый из нас прошел колоссальный высокопрофессиональный путь, мы знаем, каким способом грамотно делать ваш личный веб-сайт, продвинуть его на 1 место, конвертировать web-трафик в заказы. У нас имеется для Лично для вас бесплатное предложение по раскрутке любых интернет-ресурсов. Мы ждем Вас!

    сео онлайн бесплатно <a href=https://seoturbina.ru>seo продвижение сайта бесплатно</a>

  • Если автомобильное стекло трескается и потребуется замена, то вам в автомобильном сервисе несколько типов стеклов: старое и новое. От вас зависит какое вы выбирите.

    Автомобильные стёкла, как и любые другие авто зап. части машины, делятся на уникальные и от производителей третьих фирм. Уникальные авто стекл выпускаются либо на автобобильном заводе, занимающемся выпуском автотранспорта, либо у поставщиков автоконцерна, выпускающих запасные части по лицензии производства, которые напрямую устанавливаются в производимые автомобили. <br /> Магазин авто FYG осуществляет Лобовые стёкла от автомобиля по всем городам страны. <br /> Установкой Лобовых стёкл от авто Занимается наша фирма.

    Полировка автомобильных стёкл. <br /> Очень часто встречающимся изъяном нового тачки несомненно является утеря лобовым стёкло от авто прозрачности из-за потёртостей, царапин, как правило, от стеклоочистителей. В пользу защиты автопассажиров производители создают лобовые стёкла от авто из довольно мягких видов стекла, что и делает этот повреждения популярным. <br /> Частые повреждения лобовых стёкл от авто бывают: незначительные, глубокие, средние повреждения. <br />FYG устанавливает автостекла как на отечественные, так и на зарубежные машины а также на габаритные автомобили. <br /> Наша компания изготавливает авто стёкла на заказ.

    Официальный дистрибьютер автостекла <a href=https://hobook.ru/>заднее стекло автомобиля</a>

  • У нас вы найдете Проектирование ЛОС, а также ббз, мы можем произвести Подбор оборудования для обустройства скважины. Бурение скважин на воду, Поиск полезных ископаемых, Ремонт систем водоснабжения.

    В Сервисе для вас естьв продажу(услуги) БИОЛОГИЧЕСКАЯ ЗАГРУЗКА, Силосы для хранения сыпучих продуктов, Пропеллерные мешалки, Ленточный фильтр-пресс, Контрольные колодцы, Блоки биологической загрузки (ББЗ), Биологическая очистка хоз.бытовых сточных вод, ОДЪЕМНЫЕ УСТРОЙСТВА И МЕТАЛЛОКОНСТРУКЦИИ Шнековые конвейеры, ВОДООЧИСТНОЕ ОБОРУДОВАНИЕ Канализационные насосные станции (КНС), ПОДЪЕМНЫЕ УСТРОЙСТВА И МЕТАЛЛОКОНСТРУКЦИИ Шнековые питатели, ОЧИСТКА ЛИВНЕВЫХ СТОЧНЫХ ВОД Пескоуловитель, НАСОСНОЕ И КОМПРЕССОРНОЕ ОБОРУДОВАНИЕ (Грунфос, КСБ, Вило, КИТ, Взлёт, ТВП) Двухроторная вакуумная воздуходувка, ВОДОПОДГОТОВКУ Установки фильтрации и предподготовки, а также все для автомойки Автомойки на базе песчанно-гравийной фильтрации.

    В Сервисе диагностирует скважины, производит Канализацию в частном доме.

    обезвоживание осадков очистных сооружений также ббз <a href=https://bbzmos.ru>ббз</a>

  • Агрегатор яндекс такси по городу Самара позволяет людям вызвать авто когда и куда угодно. Произвести заказ машины можно позвонив оператору, через сайт Я.такси, воспользоваться мобильным сервисом. Очень важно указать время когда требуется автомобиль, ваш номер сотового, адрес.

    Заказывают Я. такси с детским креслом для перевозки деток, в вечернее время после посиделок безопаснее воспользоваться такси, чем сесть в авто нетрезвым, на вокзал или в аэропорт удобнее воспользоваться такси и не искать где оставить свой транспорт. Расчёт выполняется наличным или безналичным переводом. Время прибытия Yandex такси составляет от трех до 10 минут в среднем.

    Преимущества работы в нашем Я. такси: Моментальная регистрация в приложение, Незначительная комиссия, Оплата мгновенная, Постоянный поток заказов, Оператор круглосуточно на связи.

    Для работы в такси владельцу автомобиля следует оформиться лично и транспортное средство, это займёт не более пяти минут. Процент агрегатора будет составлять не свыше 20 % отдохода. Вы сможете получить заработную плату в любое время. У вас всегда будут заявки. Если будутвопросы сможете установить связь с круглосуточно функционирующей службой поддержки. Яндекс такси даёт возможность людям быстро добраться до места назначения. Заказывая данное Я. такси вы получите первоклассный сервис в г. Самара.

    работа таксистом : <a href=https://centrsnab163.ru>работа в яндекс такси на автомобиле компании</a>

  • Всем привет! <br /> Нашел интересные новости на этом сайте: http://limonos.ru : <br /> <a href=http://limonos.ru/arhitektura/>архитектура примеры</a> готическая архитектура <br /> новости шоу бизнеса россии последние http://limonos.ru/novosti-shou-biznesa/ <br /> http://limonos.ru/6962-puteshestvie-k-vilyuchinskomu-vulkanu.html <b> Путешествие к Вилючинскому вулкану </b> <br /> <a href=http://limonos.ru/21-otel-dvorec-v-samom-serdce-parizha.html> Отель-дворец в самом сердце Парижа </a> <b> Отель-дворец в самом сердце Парижа </b>

  • Our goal at vape4style.com is to deliver our clients along with the very best vaping experience achievable, helping them vape snappy!. Based in New York City as well as in service since 2015, our experts are actually a personalized vaping supermarket offering all kinds of vape mods, e-liquids, pure nicotine sodiums, shell devices, tanks, rolls, and also various other vaping extras, such as batteries as well as exterior chargers. Our e-juices are constantly new given that our team not simply market our products retail, however also distribute to neighborhood New York City retail stores as well as provide retail choices. This enables our team to constantly spin our supply, supplying our consumers and also retail stores with one of the most best supply possible.

    If you are a vaper or even making an effort to leave smoke, you remain in the right spot. Desire to spare some funds present? Rush and also join our email newsletter to receive exclusive club VIP, vape4style rebates, promos and also complimentary giveaways!

    We are actually an unique Northeast Yihi rep. We are also authorized reps of Poor Drip, Harbor Vape, Charlie’s Chalk Dirt, Beard Vape, SVRF through Saveur Vape, Ripe Vapes, Smok, Segeli, Shed Vape, Kangertech, Triton and many more. Do not find one thing you are actually looking for on our web site? Certainly not a complication! Simply let our company understand what you are searching for as well as our team will certainly locate it for you at a affordable price. Possess a concern regarding a particular item? Our vape specialists are going to rejoice to supply more information about everything our company offer. Just deliver us your concern or even contact us. Our team is going to rejoice to aid!

    best tobacco flavored ejuice retail store – <a href=https://vape4style.com/products/faucon-rdta-by-yihi-sx-mini>Yihi Faucon RDTA</a>

  • Главный сервис Яндекс такси даёт возможность вам вызвать автов любую точку города. Сделать заказ авто вы можете тремя способами: по телефону через оператора, на сайте Яндекс такси, мобильное приложение. Требуется назвать свой номер сотового, местонахождение, время когда нужна автомобиль.

    Можно заказать Я. такси вместе с детским креслом для перевозки деток, вечером после посиделок лучше прибегнуть к Я. такси, чем, например, сесть в транспортное средство нетрезвым, в аэропорт или на вокзал спокойнее пользоваться Яндекс такси и не искать где разместить свою машину. Расчёт происходит безналичным или наличным переводом. Время приезда Яндекс такси составляет от 5 до семи минут в среднем.

    Преимущества работы в нашем такси: Быстрая регистрация в приложение, Небольшая комиссия, Выплаты мгновенные, Постоянный поток заказов, Диспетчер круглые сутки на связи.

    Для работы в Я. такси водителю необходимо зарегистрироваться самому и автомашину, все это займёт пять мин. Наша комиссия будет составлять не более 15 % отдохода. Вы можете с легкость получать заработную плату в любое время. У вас всегда обязательно будут заказы. Если будутвопросы сегодня можно соединиться с круглосуточно действующей службой поддержки. Яндекс такси даёт возможность гражданам очень быстро добраться до места назначения. Заказывая современное Яндекс такси вы приобретаете люксовый сервис в городе.

    работа в такси на своей машине самара : <a href=https://centrsnab163.ru>яндекс такси вакансии</a>

  • Hello! Мы -студия разработки и создания web-сайтов. И меня зовут Антон, я учредитель большой группы профессионалов, разработчиков, специалистов, рерайтеров/копирайтеров, линкбилдеров, link builders, маркетологов, копирайтеров, оптимизаторов. Мы — команда амбициозных специалистов с 8-летним профессиональным опытом работы в области фриланса. Ваш интернет-сайт выйдет с нашей командой на новую высоту. Для вас мы предлагаем высококачественную раскрутку online-проектов в поисковиках! СЕО-специалисты которые сейчас задействованы в команде прошли громадный профессиональный путь, мы понимаем, каким образом грамотно создавать ваш сервис, продвинуть его на первое место, перестроить интернет-трафик в заказы. У нас сейчас есть для Всех вас бесплатное предложение по продвижению ваших online-сайтов. С нетерпением ждем Вас!

    бесплатные ссылки для продвижения сайта <a href=https://seoturbina.ru>бесплатный сео аудит</a>

  • Здравствуйте! интересный у вас сайт! <br /> Нашел класную базу кино: <b> лучшие мелодрамы русские скачать бесплатно торрент </b> <a href=http://kinoserialtv.net/>http://kinoserialtv.net/</a> <br /> Здесь: <a href=http://kinoserialtv.net/fantastika/>фантастика лучшие фильмы смотреть бесплатно 2018 2018</a> фильмы 2018 смотреть хорошем качестве бесплатно фантастика список 2018 <br /> Тут: смотреть лучшие сериалы комедии http://kinoserialtv.net/komediya/ список 2019 <br /> Тут: смотреть лучшие новинки мелодрам 2019 http://kinoserialtv.net/melodrama/ рейтинг 2019 <br /> Тут: http://kinoserialtv.net/12216-zarazhenie-contagion-2011.html <b> Смотреть Заражение / Contagion (2011) онлайн бесплатно </b> <br /> Здесь: http://kinoserialtv.net/14755-2-sezon-terrora-rasskazhet-o-prizrake-vremen-vtoroy-mirovoy.html

  • Привет всем участникам форума! интересный у вас сайт! <br /> Нашел обширную базу кино: <b> спартак смотреть сериал в хорошем качестве 720 </b> <a href=http://inspacefilm.ru/>http://inspacefilm.ru/</a> <br /> Здесь: Лучшие семейные фильмы онлайн http://inspacefilm.ru/semeynyy/ рейтинг 2018 <br /> Здесь: смотреть сериал меч 2 онлайн в хорошем http://inspacefilm.ru/serialy/ рейтинг 2018 <br /> Тут: <a href=http://inspacefilm.ru/triller/>смотреть бесплатно триллеры ужасы хорошего качества</a> лучшие триллеры детективы онлайн список 2018 <br /> Здесь: http://inspacefilm.ru/7188-posle-raboty-after-hours-1985.html <b> Смотреть После работы / After Hours (1985) онлайн бесплатно </b> <br /> Тут: http://inspacefilm.ru/10831-opublikovan-polnyy-saundtrek-filma-betmen-protiv-supermena.html

  • Здравствуйте! класный у вас сайт! <br /> Нашел обширную базу кино: <b> мультфильмы смотреть онлайн в хорошем качестве 720 </b> <a href=http://kinovalenok.tv/>http://kinovalenok.tv/</a> <br /> Тут: семейный фильм онлайн бесплатно в хорошем качестве http://kinovalenok.tv/semeynyy/ список 2018 <br /> Тут: сериалы тнт смотреть бесплатно в хорошем качестве http://kinovalenok.tv/serialy/ рейтинг 2019 <br /> Тут: <a href=http://kinovalenok.tv/triller/>смотреть лучшие триллеры по рейтингу зрителей</a> смотреть лучшие триллеры 2018 2019 рейтинг 2019 <br /> Здесь: http://kinovalenok.tv/316-prikvel-predystoriya-seriya-2.html <b> Спартак: Боги арены / Spartacus: Gods of the Arena (Приквел, предыстория) Серия 2 </b> <br /> Здесь: http://kinovalenok.tv/13893-obyavleny-nominanty-na-britanskuyu-premiyu-bafta.html

  • Созданная нами знаменитая компания Группа компаний ЩВРП Железногорск (Курская область) проводит современным способом видеодиагностикутехнических систем, сетей хозяйственно-бытовой, сетей хоз. бытовых, инженерных систем, ливневой канализации и так далее. <br /> Телеинспекция труб осуществляем специальной видео камерой, которая двигается по трубе и передаёт вид на видеомонитор и сразу проводится видеозапись изображения. <br /> Такая видиодиагностика позволяет определить качество стыков и стенок трубопроводов, места расположения изъянов, свищей и иных дефектов, обнаружить засоры и посторонние элементы, несанкционированные врезки и тому подобное. Видеоинспекция также может быть применена и при приёме трубопроводов после завершения выполнения строительных работ, проведения ремонта. <br /> Наибольшим положительным моментом устройства телеинспекции является сегодня ее мобильность, легкость доступа к трубам, а кроме того возможность получать изображение внутренних составляющих трубы.

    Наша производственная компания Открытое акционерное общество МПЦУ Междуреченск <br /> действует на объектах как индивидуальных так и государственных предприятиях.

    Полная очистка скважин – <a href=https://synergy90.ru>Геофизическое исследование скважин на воду</a>

  • Avatar użytkownika viking

    @Dawid: Musisz się nauczyć debugować swój kod. Po pierwsze: włącz pełne raportowanie błędów za pomocą error_reporting. Po drugie, jeśli masz rzucony wyjątek wyświetl go. Opis “mam problem z wyświetlaniem” nic kompletnie nie mówi.

  • Cześć, mały problem przy wyświetlaniu, starałem się też ręcznie dodać tabele w bazie danych, ale problem istnieje dalej. Jakieś rozwiązanie?

  • Avatar użytkownika viking

    @Jaras: Napisz jakie to konkretnie błędy bo inaczej ciężko będzie pomóc. U mnie działa.

  • Przy tworzeniu tabeli wyskakują błędy.

Dodaj komentarz

*
Nazwa zostanie wyświetlona wraz z komentarzem. Możesz też utworzyć nowe konto w serwisie, dzięki czemu uzyskasz dodatkową funkcjonalność.
*
Akceptowana jest ograniczona składnia Textile. Wszystkie tagi HTML zostaną usunięte.