Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu mysql Kanał ATOM (tag: mysql)

Autor wpisu: singles, dodany: 03.02.2013 22:58, tagi: mysql, php

Kolejną ksiażką, którą otrzymałem do zrecenzowania od Wydawnictwa Helion jest **PHP i MySQL dla każdego”. Autorem jest Marcin Lis, a ksiażka jest „świeżynką”, ponieważ została wydana w roku 2013.

PHP - MySQL dla każdego

PHP – MySQL dla każdego

Uprzedzając – czy jest to artykuł sponsorowany? W jakiś sposób tak – książka zostanie u mnie i zostanie przeznaczona na nagrodę na następnym meet.php. Czy moje opinie są sponsorowane? Zdecydowanie nie.

Treść

Ksiażka jest typowym wprowadzeniem do języka PHP jak i MySQLa. O ile do „dla każdego” mógłbym się przyczepić (patrz podsumowanie recenzji), to zdecydowanie jest to ksiażka dla początkujących.

Ksiażka podzielona jest na 3 części. Pierwsza tyczy się stricte PHP, druga MySQLa, a trzecia łączenia wcześniej wymienionych.

Tak więc w przypadku PHP mamy spory rozdział o instalacji, potem o zmiennych, poprzez instrukcje sterujące itd. Znalazło się także miejsce na rozdział o programowaniu obiektowym (który jest 2 razy krótszy niż rozdział o instrukcjach warunkowych). Po opisaniu podstaw PHP przychodzi czas na opisanie podstaw MySQLa. No i ponownie mamy instalację, następnie czytamy o tym czym są tabele, jak je obsługiwać i jak dodawać, pobierać dane. Część trzecia opisuje na podstawowych przykładach, jak łączyć wspomniane technologie na przykładzie takich rzeczy jak system newsów czy też generowanie statystyk.

Po zapoznaniu się z ksiażką stwierdzam, co następuje – 2/3 ksiazki to tak naprawdę przeredagowany manual dla PHP i MySQLa wydrukowany na papierze, z tym że z większą ilością przykładów. Co nie znaczy, że to coś złego. Cieżko powiedzieć coś wiecej – nie zauważyłem jakiś błedów merytorycznych, aczkolwiek mam kilka uwag:

  • z niektórych rozdziałów bym zrezygnował – skoro to dla poczatkujących to zostawmy programowanie obiektowe w spokoju, tym bardziej, że jest potraktowane mocno po łebkach,
  • ksiażka jest z roku 2013, a o PHP 5.4 ani słowa – aczkolwiek, może to być kwestia procesu wydawniczego,
  • umieszczanie w tekście określen „implozja i eksplozja” nie wydaje się mi pomysłem trafnym ;),
  • w ksiażce w jednym miejscu znajduje sie kawałek kodu w JS (do walidacji formularza), który jest moim zdaniem totalnie zbędny,
  • w przypadku ksiażki dla początkujących polecałbym instalację środkowiska za pomocą gotowego pakietu, np. XAMPa, a nie od zera, ale to tylko moja osobista opinia,
  • w rozdziale na temat współpracy PHP z MySQLem przykłady podawane są w 3 formach: mysqli proceduralny i obiektowy oraz PDO (tutaj wielki plus za porzucenie mysql_*), natomiast moim zdaniem w ksiażce dla początkujących jedna forma wystarczy – osobiście wybrałbym PDO,
  • spaghetti code – niestety, ksiażka prezentuje mocno zaawansowany „spaghetti code” – uważam, że wprowadzenie do prostego systemu szablonów nie jest czymś, z czym początkujący programista sobie nie poradzi

Jakość wydania

Książka wydana została w miękkiej oprawie i NIE pochodzi z wydania „eko”. Zawartość zmieszczono na ponad 600 stronach stosunkowo grubego papieru o wysokiej białości. Formatowanie jest bardzo dobre, ważne rzeczy odpowiednio wyróżnione, kod w przykładach drukowany czcionką o stałej szerokości z pogrubionymi słowami kluczowymi. Jeśli chodzi o język kodu, to tak jak nie znoszę listingów w innym języku niż angielski, w ksiażce dla początkujących mogę przymknąć oko.

Jednak na fakt tego, że raz listingi są po polsku a raz po angielsku, to oka już nie przymykam.

Podsumowanie

Mam problem z takimi ksiażkami.. Mianowicie, chodzi mi o człon „Dla każdego”. No i tutaj jest problem. Programowanie nie jest dla każdego. I nie, jestem daleki od wywyższania się. Bo tak samo nie dla każdego jest śpiewanie, malowanie, gotowanie czy też praca z klientem.

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

Autor wpisu: Tomasz Kowalczyk, dodany: 27.01.2013 22:13, tagi: mysql, php

Myślałem trochę nad całą serią wpisów w tej kategorii i zauważyłem, że bardzo mało (właściwie wcale nie ma) jest wpisów o bazach danych. Na blogu znajduje się już wiele tekstów z linkami o PHP, JavaScripcie i innych językach programowania, a … #LINK#

Autor wpisu: Tomasz Kowalczyk, dodany: 25.01.2013 11:04, tagi: php, doctrine, mysql, symfony, symfony2

Jakiś czas temu chciałem poeksperymentować trochę z bazą danych jednego z projektów FLOSS w Symfony2.         Importując dane z MySQLa poprzez komendę zostałem przywitany przez Doctrine2 wyjątkiem: [Doctrine\DBAL\DBALException] Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support … #LINK#

Autor wpisu: Jakub, dodany: 27.12.2012 22:58, tagi: apache, mysql, php

Instalacja wirtualnego serwera na systemie Ubuntu, jest trudniejsza niż w przypadku pospolitego Windows’a. Należy jednak pamiętać, że Linux o wiele lepiej spełni zadanie wirtualnej maszyny z wielu oczywistych przyczyn. A więc zaczynajmy: 1. Zaczynamy od upewniania się, czy nasze oprogramowanie jest w pełni aktualne:

1sudo apt-get update

2. Następnie instalujemy fundament naszego serwera, czyli Apache:

1sudo apt-get install apache2

3. Teraz PHP:

1sudo apt-get install php5

Opcjonalnie, możemy jeszcze teraz doinstalować najważniejsze biblioteki PHP:

1234sudo apt-get install php-pear sudo apt-get install php5-xsl sudo apt-get install php5-gd sudo apt-get install php5-ming

4. Baza danych MySQL:

1sudo apt-get install mysql-server

Aby serwer MySQL był w pełni zintegrowany z PHP, musimy dołączyć jeszcze odpowiednie komponenty:

12sudo apt-get install libapache2-mod-auth-mysql sudo apt-get install php5-mysql

5. Dla ułatwienia naszej pracy, warto doinstalować jeszcze phpMyAdmn. Wklejamy do konsoli:

1sudo apt-get install phpmyadmin

I postępujemy zgodnie ze wskazówkami instalatora. Następnie wpisujemy komendę:

1sudo gedit /etc/apache2/apache2.conf

Otworzy nam się pewien plik, na koniec którego doklejamy poniższą linijkę:

1Include /etc/phpmyadmin/apache.conf

Zapisz i zamknij plik.   Gratulację! Od teraz, masz w pełni działający serwer!

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

Autor wpisu: Śpiechu, dodany: 08.10.2012 21:56, tagi: mysql

Zgodnie z obietnicą dzisiaj druga część. Zwiększamy poziom trudności o relację wiele-do-wielu.

Na początek dorzucamy tabelę Ficzer zawierającą dodatkowe bajery, o które ma być wzbogacony artykuł:

CREATE TABLE IF NOT EXISTS `Ficzer` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`nazwa` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `Ficzer` (`id`, `nazwa`) VALUES
(1, 'Podświetlenie'),
(3, 'Pogrubienie'),
(5, 'Pochylenie');

Zaraz za nią tworzymy tabelę pośredniczącą Ogloszenie_Ficzer:

CREATE TABLE IF NOT EXISTS `Ogloszenie_Ficzer` (
  `ogloszenie_id` INT(11) NOT NULL,
  `ficzer_id` INT(11) NOT NULL,
  PRIMARY KEY (`ogloszenie_id`,`ficzer_id`),
  KEY `ficzer_id` (`ficzer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
ALTER TABLE `Ogloszenie_Ficzer`
  ADD CONSTRAINT `Ogloszenie_Ficzer_ibfk_4` FOREIGN KEY (`ficzer_id`) REFERENCES `Ficzer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `Ogloszenie_Ficzer_ibfk_3` FOREIGN KEY (`ogloszenie_id`) REFERENCES `Ogloszenie` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Procedura składowana ogloszenie_history musi zostać rozbudowana o obsługę dodanych tabel (a raczej tabeli, bo wystarczy nam tabela pośrednicząca). Dokonamy „spłaszczenia” struktury bazy w wierszu historii wymieniając wszystkie ficzery rozdzielone średnikami. Dorzucamy pole ficzers do OgloszenieHistory:

ALTER TABLE `OgloszenieHistory` ADD COLUMN `ficzers` text DEFAULT NULL;

Poniżej uaktualniony kod procedury składowanej:

DELIMITER $$
CREATE PROCEDURE `ogloszenie_history`(IN `id` INT, IN `change_type` ENUM('created','modified','deleted')) 
MODIFIES SQL DATA 
BEGIN 
  DECLARE p_user_id INT; 
  DECLARE p_data TEXT;
 
  # Ciag tekstowy zawierajacy ficzer_id;ficzer_id;...
  DECLARE p_ficzers TEXT DEFAULT NULL;
 
  # Pojedynczy wiersz kursora.
  DECLARE p_ficzer INT;
 
  # Blokada kursora gdy braknie wynikow.
  DECLARE p_last_ficzer INT DEFAULT FALSE;
 
  # Deklaracja kursora przechodzacego po wszystkich ficzerach ogloszenia.
  DECLARE cur_ficzer CURSOR FOR SELECT ficzer_id FROM Ogloszenie_Ficzer WHERE ogloszenie_id=id;
 
  # Ustawienie blokady kursora.
  DECLARE continue handler FOR NOT found SET p_last_ficzer = TRUE;
 
  # Wyciagam dane ze zmienianego wiersza i wrzucam do zadeklarowanych wczesniej zmiennych.
  SELECT modified_by, DATA INTO p_user_id, p_data FROM Ogloszenie WHERE id=id LIMIT 1;
 
  OPEN cur_ficzer;
  ficzer_loop: LOOP
    FETCH cur_ficzer INTO p_ficzer;
    IF p_last_ficzer THEN
      LEAVE ficzer_loop;
    END IF;
 
    # Sklejam kolejne wartosci.
    SET p_ficzers = CONCAT_WS(';', p_ficzers, p_ficzer);
  END LOOP;
  CLOSE cur_ficzer;
 
  # Wrzucam wiersz do historii.
  INSERT INTO OgloszenieHistory (ogloszenie_id, change_type, user_id, DATA, ficzers) 
    VALUES (id, change_type, p_user_id, p_data, p_ficzers);
 
END$$
DELIMITER ;

Dzięki zastosowaniu kursora zbieramy sobie każdorazowo bieżące wartości tabeli pośredniczącej. Ostatnią rzeczą jest dodanie wyzwalaczy:

DROP TRIGGER IF EXISTS `new_ficzer`;
DELIMITER //
CREATE TRIGGER `new_ficzer` AFTER INSERT ON `Ogloszenie_Ficzer`
  FOR EACH ROW BEGIN
    CALL ogloszenie_history (NEW.ogloszenie_id, 'modified');
END//
DELIMITER ;
DROP TRIGGER IF EXISTS `delete_ficzer`;
DELIMITER //
CREATE TRIGGER `delete_ficzer` BEFORE DELETE ON `Ogloszenie_Ficzer`
  FOR EACH ROW BEGIN
    CALL ogloszenie_history (OLD.ogloszenie_id, 'modified');
END//
DELIMITER ;

Stosując takie rozwiązanie każda zmiana jest rejestrowana w dzienniku zmian. Minusem jest to, że następuje gwałtowny przyrost wierszy (dodanie 10 ficzerów do ogłoszenia powoduje dodanie 10 wierszy historii, skasowanie to samo). Jeśli bardzo zależy nam na ograniczeniu liczby wierszy trzeba zastanowić się nad jakimś automatem odpalanym cyklicznie z CRONa kasującym starą historię lub bardziej wyrafinowanym — wyłapującym „stany pośrednie” (co zresztą też jest niezłym pretekstem do napisania na blogu ;-) ).

PS.: Interesujecie się DARTem? Jeszcze trochę ponad 100 defektów i będzie milestone 1.

Autor wpisu: Śpiechu, dodany: 09.09.2012 22:15, tagi: mysql

Ponieważ dawno nie pisałem o bazach danych, dzisiaj coś dla miłośników wyzwalaczy i procedur składowanych w MySQL. Ile razy myśleliście, że fajnie by było żeby coś „samo się robiło”? Taką samosię można napisać dosyć łatwo jeśli chcemy stworzyć mechanizm śledzenia historii rekordu. Wpis rozbiję na dwie części z uwagi na to, że w następnej skomplikuję całość o tworzenie historii rekordu z wielu tabel.

Załóżmy, że mamy tabelę Ogloszenie, w której trzymamy dane, które chcemy śledzić. Ma następującą strukturę:

CREATE TABLE IF NOT EXISTS `Ogloszenie` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `modified_by` INT(11) NOT NULL,
  `data` TEXT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

Tabela śledząca ogłoszenie będzie wyglądała mniej więcej tak (nie śmiać mi się z polsko-angielskich hybryd nazewniczych):

CREATE TABLE IF NOT EXISTS `OgloszenieHistory` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `ogloszenie_id` INT(11) NOT NULL,
  `change_type` enum('created','modified','deleted') NOT NULL,
  `user_id` INT(11) NOT NULL,
  `event_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `data` TEXT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

Wiemy, że możemy podczepiać się pod zmiany w bazie danych za pomocą wyzwalaczy (triggerów). Tworząc historię wystarczy śledzić zmiany w postaci zapytań typu insert, update i delete. Wyzwalacze będą różnić się właściwie tylko typem wykonanego zapytania. Nie wiem jak wam, ale mnie na kilometr „zajechało” redundancją kodu wyzwalaczy, więc napiszemy sobie procedurę składowaną, którą każdy z wyzwalaczy będzie odpalał. Jest to najtrudniejsze zadanie (kod procedur wykrzacza się jak szalony).

DELIMITER $$
CREATE PROCEDURE `ogloszenie_history`(IN `id` INT, IN `change_type` ENUM('created','modified','deleted')) 
MODIFIES SQL DATA 
BEGIN 
  DECLARE p_user_id INT; 
  DECLARE p_data TEXT; 
 
  # Wyciagam dane ze zmienianego wiersza i wrzucam do zadeklarowanych wczesniej zmiennych.
  SELECT modified_by, DATA INTO p_user_id, p_data FROM Ogloszenie WHERE id=id LIMIT 1;
 
  # Wrzucam wiersz do historii.
  INSERT INTO OgloszenieHistory (ogloszenie_id, change_type, user_id, DATA) 
    VALUES (id, change_type, p_user_id, p_data);
 
END$$
DELIMITER ;

Zwróćcie uwagę na pole change_type, którego dopuszczalne wartości to created, modified i deleted, czyli dokładnie takie jak w tabeli OgloszenieHistory. Skutecznie zawęzi nam to możliwość „zatrucia” historii niezrozumiałymi typami zmian. Pozostało zrobienie wyzwalaczy:

DROP TRIGGER IF EXISTS `inserted_ogloszenie`;
DELIMITER //
CREATE TRIGGER `inserted_ogloszenie` AFTER INSERT ON `Ogloszenie`
 FOR EACH ROW BEGIN
  # Podpinamy sie po insercie dysponujac swiezo auto inkrementowanym ID wiersza.
  CALL ogloszenie_history(NEW.id, 'created');
END//
DELIMITER ;
DROP TRIGGER IF EXISTS `updated_ogloszenie`;
DELIMITER //
CREATE TRIGGER `updated_ogloszenie` AFTER UPDATE ON `Ogloszenie`
 FOR EACH ROW BEGIN
  # Podajemy id zmienionego rekordu.
  CALL ogloszenie_history(NEW.id, 'modified');
END//
DELIMITER ;
DROP TRIGGER IF EXISTS `deleted_ogloszenie`;
DELIMITER //
CREATE TRIGGER `deleted_ogloszenie` BEFORE DELETE ON `Ogloszenie`
 FOR EACH ROW BEGIN
  # Zanim baza skasuje wiersz zapiszemy sobie TO wydarzenie.
  CALL ogloszenie_history(OLD.id, 'deleted');
END//
DELIMITER ;

Śledzenie historii przedstawione powyżej jest o tyle dobre, że zwalnia nas z pisania jakiegokolwiek kodu po stronie aplikacji. Wszystko robi za nas baza. Dodatkowo mamy pełny wgląd kto i kiedy zmieniał dane. Przykładowe wpisy w tabeli OgloszenieHistory:

id, ogloszenie_id, change_type, user_id, event_date,           data
1   1              'created'    1        '2012-09-05 18:09:03' 'First data'
2   1              'modified'   2        '2012-09-05 18:09:16' 'Modified data'
3   1              'modified'   1        '2012-09-05 18:09:29' 'Modified data drugi raz'
4   2              'created'    1        '2012-09-05 18:09:37' 'Second data'
5   1              'deleted'    2        '2012-09-05 18:42:42' 'Modified data drugi raz'

W zastosowaniach praktycznych nie mamy właściwie do czynienia z bazami bez relacji, więc taka prosta historia na niewiele się zda. W następnej części wprowadzę śledzenie relacji typu wiele-do-wielu. Kiedy będzie następna część? Wtedy kiedy będzie mi się chciało pisać ;-)

Autor wpisu: Tomasz Kowalczyk, dodany: 02.09.2012 20:19, tagi: mysql

Na pewno wpadliście kiedyś w pułapkę, w której podczas testowania wydajności / sposobu działania wpisaliście w okienko phpMyAdmina lub bezpośrednio w konsolę MySQLa nie do końca przemyślane zapytanie. Jeśli zawierało jakiś błąd składniowy, to sprawa jest prosta – na ekranie … #LINK#
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.