Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: batman, dodany: 09.08.2010 20:00, tagi: zend_framework

Dzisiejszym wpisem z serii “Poradniki” wracam do pierwotnych założeń, jakie przyświecały powstaniu tej kategorii, czyli “wpisy ku pamięci”. Ich celem jest pozostawienie w ogólnodostępnym miejscu informacji na temat konkretnego zadania tak, by nie musieć ponownie szukać rozwiązania, które na ogół jest banalne. Tyle tytułem wstępu, do rzeczy.

Każdy kto miał do zrobienia stronę z galerią zdjęć, stawał przed wieloma problemami z tym związanymi. Począwszy od stworzenia bezpiecznego i funkcjonalnego formularza, na przechowywaniu zdjęć kończąc. Wszystkie problemy można rozwiązać w bardzo prosty sposób w kilkunastu wierszach kodu.

Co musimy zrobić? Stworzyć galerię zdjęć w serwisie Picasaweb, a następnie dodać do niej zdjęcia. Jeśli zdjęć mamy dużo, korzystamy z aplikacji desktopowej – Picasa. Na koniec pozostanie napisanie prostego skryptu, który pobierze zdjęcia.

/* cache */
$frontendOptions = array(
   'lifetime' => 3600 * 3,
   'automatic_serialization' => true
);
$backendOptions = array(
	'cache_dir' => APPLICATION_PATH . '/../data/cache'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);

/* utworzenie obiektu, ktory pobierze zdjecia */
$service = new Zend_Gdata_Photos();
$photos = array();

/* jesli nie ma zdjec w cache, pobierz je z Picasy */
if(!$photos = $cache->load('photos')) {
	/* obiekt zapytania do albumow zdjec */
	$query = new Zend_Gdata_Photos_AlbumQuery();
	/* ustawienie nazwy uzytkownika, z konta ktorego beda pobierane zdjecia */
	$query->setUser('some.username');
	/* ustawienie nazwy albumu, z ktorego beda pobierane zdjecia */
	$query->setAlbumName('SomeAlbumame');
	/* pobranie zdjec */
	$albumFeed = $service->getAlbumFeed($query);
	/* pobranie informacji o sciezce do zdjec */
	foreach($albumFeed as $photo) $photos[] = (string)$photo->content->src;
	/* zapisanie danych do cache */
	$cache->save($photos, 'photos');
}

Uważni obserwatorzy na pewno zauważą, iż scieżki, kierują do zdjęć pełnowymiarowych. Na szczęście Picasa tworzy miniaturki zdjęć i “przechowuje” je w folderach o nazwach zawierających szerokość zdjęcia. Aby dostać się do miniaturek, wystarczy użyć funkcji pathinfo.

$info = pathinfo($photo);
$mini = $info['dirname'] . '/s150/' . $info['basename'];

W miejscu s150 można wstawić dowolny inny rozmiar zdjęcia poprzedzony małą literą s, np s237.

Autor wpisu: eRIZ, dodany: 08.08.2010 23:27, tagi: php

Od momentu wprowadzenia namiastki obiektów do naszego kochanego języka, coraz bardziej zaczęły nasilać się narzekania, że PHP jest sto lat za konkurencją pod wieloma względami. Pewnie lista narzekań ciągnęłaby się aż do wyczerpania zapasów papieru toaletowego w WC, ale na pewne rzeczy progamista nie ma po prostu wpływu.

Jeśli nie da się czegoś rozwiązać wprost, zawsze można spróbować to… obejść. Wbrew pozorom, w programowaniu zdarza się to nierzadko. ;)

A o czym chcę napisać? O wyrzucaniu błędów przez PHP zamiast wyjątków.

Autor wpisu: batman, dodany: 08.08.2010 19:08, tagi: php

Microsoft wypuścił drugą wersję sterownika SQL Server przeznaczonego dla języka PHP. W nowej wersji dodano przede wszystkim wsparcie dla PDO. Dodanie wsparcia dla PDO nie oznacza, że przestaną działać dotychczasowe rozwiązania. Wydanie drugiej wersji sterownika było dobrą okazją do przepisania biblioteki odpowiedzialnej za łączność z bazą danych SQL Server. Nowa wersja została tak napisana, aby wszystkie wspóle elementy wydzielić do osobnej warstwy, z której korzystają różne mechanizmy do łączenia się z bazę.

Jak widać na powyższym obrazku (źródło: Microsoft SQL Server Driver for PHP Team Blog) w drugiej wersji sterownika można korzystać z dwóch sposobów łącznia się bazą, co w przypadku kod będzie wyglądało nastęująco.

<?php
// SQLSRV driver:
$serverName = "(local)\sqlexpress"; 
$connectionOptions = array( "Database"=>"AdventureWorks" );

/* Connect to SQL Server using Windows Authentication. */ 
$conn = sqlsrv_connect( $serverName, $connectionOptions );

/* Get products by querying against the product name.*/ 
$tsql = "SELECT ProductID, Name, Color, Size, ListPrice FROM Production.Product";

/* Execute the query. */ 
$getProducts = sqlsrv_query( $conn, $tsql );

/* Loop thru recordset and display each record. */ 
while( $row = sqlsrv_fetch_array( $getProducts, SQLSRV_FETCH_ASSOC ) ) 
{ 
	print_r( $row ); 
}

/* Free the statement and connection resource. */
sqlsrv_free_stmt( $getProducts );
sqlsrv_close( $conn );
<?php
// PDO_SQLSRV driver:
$serverName = "(local)\sqlexpress"; 

/* Connect to SQL Server using Windows Authentication. */ 
$conn = new PDO( "sqlsrv:server=$serverName;Database=AdventureWorks" );

/* Get products by querying against the product name.*/ 
$tsql = "SELECT ProductID, Name, Color, Size, ListPrice FROM Production.Product";

/* Execute the query. */ 
$getProducts = $conn->query( $tsql );

/* Loop thru recordset and display each record. */ 
while( $row = $getProducts->fetch( PDO::FETCH_ASSOC ) ) 
{ 
	print_r( $row );
}

/* Free the statement and connection resource. */
$getProducts = NULL;
$conn = NULL;

źródło: Microsoft SQL Server Driver for PHP Team Blog

Autor wpisu: cojack, dodany: 08.08.2010 13:55, tagi: php

PHP Jako iż każdy chce po sobie zostawić ślad tak i ja mam taki plan. Moje założenie: Napisać prosty i ciekawy system, który byłby fundamentem do tworzenia stron, stąd też nazwa Basic PHP Develop Tools, czyli podstawowe narzędzia. Zarazem podstawowe narzędzia i pełna moc w pisaniu aplikacji. Na pewno nie jeden z Was spotkał się z Drupalem, i opiniami o nim jaki to on nie jest wyczesany, jaki to on jest wspaniały, no cud malina. Tak tylko czy ktoś próbował w nim pisać cokolwiek? No właśnie i ja podziękuje za taką fanaberię. Prędzej bym „wyklikał” w nim moduł niż go napisał. Ale nie w tym sęk, chciałbym by ta aplikacja nie przerodziła się w Frameworka, nie chce nazywać tego Frameworkiem, i nie chce by ktokolwiek o nim w ten sposób myślał. Bardzo nie lubię tego stwierdzenia, i w ogóle nie przypada mi do gustu, powiem więcej wręcz się nim brzydzę.

Założenia do BDT

- W pełni obiektowy - Podstawowe narzędzia dla developera - Darmowy na licencji GPL

to by było na tyle ;)

Użyte narzędzia

- Horde Routes - Cache by MatheW ( linki na dole ) - Laptop, klawiatura, myszka, monitor, trochę palców… własne pomysły + podpatrzone.

Co już mam zrobione

- Obsługa akcji, - Routing (ta już był tylko zaimplementować), - Cache (j/w), - System szablonów ( php + html, żadne smarty opty i inne śmiecie ), - Obsługa błędów ( wyjątki + trigger_error ), - Obsługa SQL w 40%, - Confingi ( w XML )

Czego jeszcze nie mam zrobione

- Requesty (ale mam już koncept) - Weryfikacja danych (j/w) - Headery (szczerze, to mi się w to nie chce bawić, oprócz takich podstawowych jak 404 itp) - MultiLanguage ( dla błędów to będzie na 100% gettext, i l18n dla treści ) - Instalator ( jeszcze nie wiem czy będzie )

Co chcę uzyskać

Chcę napisać wydajny system, który usprawni mi pracę, która sprawi mi jeszcze więcej przyjemności niż Wam się wydaje, gdyż dla mnie programowanie to frajda. Olałem Doctrine, gdyż z tymi pajacami z dev nie można się w żaden sposób dogadać, myślą że pozjadali wszystkie rozumy i są najlepsi na świecie, także ORM będzie trochę inny niż wszystkie. Piszę swój system do zarządzania SQL’em, oczywiście nie będzie tam żadnych INSERT, UPDATE czy DELETE w kodzie wykonanego wszystko będzie oparte o język proceduralny PL/pgSQL nazwałem tą aplikację PGFM (PostgreSQL Function Mapper) … ( przy okazji refaktoryzacji kodu już zdążyłem zmienić nazwy większości klas, także ciekawe co z tego wyjdzie…) . Czyli dodanie rekordów do bazy danych czy ich aktualizacja lub/i usunięcie będzie się wykonywało poprzez procedury. W pewnym stopniu jest to przeniesienie logiki aplikacji do SQL’a, ale dlaczego nie? Jest to ciekawe rozwiązanie i nigdzie wcześniej nie widziałem takiego rozwiązania ( no prawie nigdzie ale nie mogę powiedzieć gdzie ;] domyślcie się gdzie ).

Dlaczego darmowy?

Dlatego że chce by każdy miał dostęp do innego spojrzenia na problem by też mógł się rozwijać analizując czyjś kod, może znajdzie ktoś jakiś błąd i pomoże mi go naprawić. Ale szczerze powiedziawszy nie liczę na to że będziecie chcieli używać tych narzędzi, nie zależy mi na tym. Piszę go dla siebie i dla firmy mojego kolegi ;)

Bezpieczeństwo

Dużą wagę przekładam na bezpieczeństwo aplikacji, zatem data wydania będzie się przeciągać w czasie, będę chciał uniknąć falstartów i śpieszyć się z tym byście ujrzeli moje wypociny, jakoś mi się nie śpieszy. Rdzeń aplikacji będzie a przynajmniej będę miał takie założenie, odporny na taki typu sql injecty, xss’y i masę innych dupereli.

Słów kilka na zakończenie

Pewnie nie jeden z Was zapyta się po co to piszę? No napisałem powyżej, chce to zrobić by zostawić jakiś ślad po sobie. Oraz piszę też to po to by się samemu rozwijać, widzieć problem i znaleźć rozwiązanie dla niego. Na prawdę fajnie się idzie owkurw**** jak coś nie wychodzi, a później olśnienie i tona euforii jak zaczyna działać. To jest właśnie to dlaczego piszę swoją aplikację. Poza tym TAO programowania.

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

Autor wpisu: Vokiel, dodany: 06.08.2010 23:00, tagi: php

Autentyfikacja HTTP

Ostatnio, podczas przenosin dość starej aplikacji na nowy serwer natknąłem się na problem z powodu wykorzystania autentyfikacji HTTP. Problem okazał się błachy, jednak w momencie przenosin i pierwszych testów miałem problem z diagnozą przyczyn takiego stanu rzeczy.

Opis sytuacji

Na wstępie krótko opiszę sytuację, objawy jakie się pojawiły. W dalszej części pokażę sposób poradzenia sobie z problemem.

Na starym serwerze PHP działał sobie jako zwykły moduł apache. Jako, że aplikacja była pisana dawno temu, wówczas system logowania oparty na autentyfikacji HTTP wydawał się wystarczający. Tym bardziej, iż była to aplikacja intranetowa. Po przenosinach na nowy serwer okazało się, że okienko autentyfikacji nie przestawało wyskakiwać nawet po podaniu poprawnego loginu i hasła. Na pierwszy ogień poszło sprawdzenie poprawności przeniesionej bazy danych, użytkownika bazy, zawartości tabel. Okazało się, że wszystko jest ok, zatem na warsztat poszedł test systemu logowania.

System logowania oparty o autentyfikację HTTP

System logowania był bardzo prosty. Pobrane dane z $_SERVER['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'] były porównywane z tymi w bazie danych. Jeśli autoryzacja nie przebiegała pomyślnie wyświetlany był odpowiedni komunikat i po trzech sekundach strona była odświeżana z ponownym wyświetleniem okienka autentyfikacji.

Skrócony na potrzeby przykładu plik index.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
if (empty($_SERVER['PHP_AUTH_USER'])) {
	header('WWW-Authenticate: Basic realm="Logowanie"');
	header('HTTP/1.0 401 Unauthorized');
	sleep(3);
	exit;
}else {
	DEFINE ('LOGINSALT','TESTOWYSALTLOGOWANIA');
 
	require_once 'class/db/db.class.php';
	require_once 'class/login.class.php';
 
	$login_string = md5($_SERVER['PHP_AUTH_USER'].LOGINSALT.md5($_SERVER['PHP_AUTH_PW']));
	$logowanie = new login($login_string);
	$logowanie->login();
	if ($logowanie->isLogged()){
		// ok
	} else {
		include 'notLogged.php';
		sleep(3);
		header('WWW-Authenticate: Basic realm="Logowanie"');
		header('HTTP/1.0 401 Unauthorized');
		exit;
	}
}
?>

Jak widać jest to bardzo proste, wręcz banalne rozwiązanie. Z tą różnicą względem podstawowych systemów opartych na .htpasswds, że dane użytkowników są przechowywane w bazie danych.

Sama klasa logowania też jest bardzo prosta. Jednak w tym wypadku, doskonale spełniała swoje założenia. Wersja odchudzona:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
/**
 * Klasa logowania
 *
 * @param string $login_string - Ciąg danych logowania md5(login+salt+md5(hasło))
 */
class login{
	/**
	 * Ciąg logowania
	 *
	 * @var string
	 */
	private $_login_string;
	/**
	 * Stan zalogowania
	 *
	 * @var bool $_logged
	 */
	private $_logged = false;
	/**
	 * Id zalogowanego użytkownika
	 *
	 * @var int
	 */
	private $_id;
	/**
	 * Konstruktor klasy logowania
	 *
	 * @param string $login_string
	 */
	public function __construct($login_string){
		$this->_login_string = $login_string;
	}
	/**
	 * Logowanie użytkownika
	 *
	 * @return bool
	 */
	public function login(){
		$db = new db_class(DB_HOST,DB_LOGIN,DB_PASS,DB_NAME);
		$query = "SELECT `ID` FROM `LISTA_USR` WHERE md5(CONCAT(`LOGIN`,'".LOGINSALT."',`PASS`))='".$this->_login_string."' ;";
		$db->sqlQuery($query);
		if ($db->sqlNumRows()>0){
			$row = $db->getRow();
			$this->_id = $row['ID'];
			$this->_logged = true;
			return true;
		}
		return false;
	}
	/**
	 * Sprawdzenie czy zalogowany
	 *
	 * @return bool $this->_logged
	 */
	public function isLogged(){
		return $this->_logged;
	}
	/**
	 * Pobranie ID zalogowanego użytkownika
	 *
	 * @return int $this->_id;
	 */
	public function getUsrId(){
		return $this->_id;
	}
}
?>

Rozwiązanie proste jak budowa cepa. Nie ma się tu nad czym rozwodzić. Niestety w trybie CGI się nie sprawdza, gdyż w zmiennej $_SERVER nie ma zmiennych $_SERVER['PHP_AUTH_USER'] oraz $_SERVER['PHP_AUTH_PW'].

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

Autor wpisu: batman, dodany: 06.08.2010 22:03, tagi: zend_framework

Dzisiaj w serwisie Zend Developer Zone pojawiła się informacja o wydaniu pierwszego milestone’a Zend Frameworka 2. Ze zmian jakie się pojawiły można wymienić:

  • usunięcie wszystkich wywołań require_once
  • migracja do przestrzeni nazw
  • całkowita przebudowa pakietu testującego
  • przepisanie modułu Zend\Session oraz dodanie nowego komponentu Zend\SignalSlot odpowiedzialnego za obsługę obserwatorów
  • dodanie przestrzeni nazw Zend\Stdlib zawierającej interfejsy dla klas rozszerzających klasy Spl

Ponadto opublikowana została mapa drogowa (roadmap) projektu zawierająca kolejne etapy powstawania drugiej wersji ZF.

Zend Framework 2.0 został udostępniony do pobrania w dwóch wersjach:

ZendFramework 2.0.0dev1 zip package ZendFramework 2.0.0dev1 tar.gz package

Autor wpisu: batman, dodany: 06.08.2010 21:45, tagi: javascript

Wraz z nadejściem Windows Vista Microsoft udostępnił użytkownikom swojego systemu operacyjnego gadżety pulpitu. Są to niewielkie aplikacje umieszczone na pasku nazwanym Windows Sidebar. Następca Visty – Windows 7 – usunął pasek, dzięki czemu gadżety stały się czymś więcej niż ładną ikonką po prawe stronie ekranu. Jako przykładowe gadżety można wymienić kalendarz, notatnik, zegar, podręczny czytnik RSS, czy też monitor zasobów komputera. Jak widać zastosowanie tych aplikacji idealnie pasuje do ich nazwy. Niemniej czasami są bardzo pomocne, ponieważ oferują szybki dostęp do konkretnych informacji.

W jakiej technologii tworzone są gadżety?

Jeśli myślicie, że do tworzenia gadżetów będzie wam potrzebne Visual Studio oraz znajomość C#, to jesteście w błędzie. Podstawową technologią w jakiej tworzy się gadżety jest Javascript. Za wygląd odpowiada HTML oraz CSS. Gadżety renderowane są tak samo jak strony internetowe, a do renderowania wykorzystany jest silnik przeglądarki Internet Explorer. Dzięki temu mamy możliwość korzystania z ActiveX, a ponieważ gadżety nie są uruchamiane w kontekście strony internetowej, nie ma zastosowania reguła tej samej domeny podczas korzystania z AJAXa. Co więcej, w gadżetach można korzystać z popularnych bibliotek Javascript (np z jQuery) oraz z Flasha. Niestety nie miałem okazji przetestować Silverlighta. Podobnie jak ma to miejsce w Adobe AIR (dla programistów Javascript), jest tylko jedno środowisko, w którym uruchamiane są gadżety. Jest to o tyle ważne, że nie trzeba martwić się o zgodność z różnymi przeglądarkami.

Struktura gadżetu

W minimalnej wersji gadżet składa się jedynie z dwóch plików – manifestu oraz pliku HTML stanowiącego treść gadżetu. Do tego zestawu można dodać pliki CSS, Javascript, grafiki oraz kolejne pliki HTML. Nic nie stoi na przeszkodzie, aby pliki umieszczać w katalogach. Po zakończeniu prac nad gadżetem należy spakować wszystko jako archiwum zip i zmienić jego rozszeżenie na .gadget. W takiej postaci możemy upublicznić nasz gadżet.

Tworzenie gadżetu

Tworzenie gadżetu rozpoczynamy od stworzenia w folderze

C:\Users\batman\AppData\Local\Microsoft\Windows Sidebar\Gadgets,

gdzie batman będzie waszą nazwą użytkownika, katalogu o nazwie Test.gadget. Ważne jest, aby pamiętać o dodaniu przyrostka (sufiksu) .gadget.

Wewnątrz katalogu tworzymy dwa pliki: gadget.xml oraz Test.html. Plik gadget.xml jest manifestem i zawiera wszystkie niezbędne informacje o naszym gadżecie. Manifest w pełnej wersji wygląda następująco

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
	<name>Test Gadget</name>
	<namespace>my.gadgets</namespace>
	<version>1.0.0.0</version>
	<author name="Maciej batman Wilgucki">
		<info url="wilgucki.pl" text="My site" />
		<logo src="logo.png" />
	</author>
	<copyright>© wilgucki.pl</copyright>
	<description>My Test Gadget</description>
	<icons>
		<icon height="48" width="48" src="icon.png" />
	</icons>
	<hosts>
		<host name="sidebar">
			<base type="HTML" src="Test.html" />
			<permissions>Full</permissions>
			<platform minPlatformVersion="1.0" />
			<defaultImage src="icon2.png" />
			<autoscaleDPI />
		</host>
	</hosts>
</gadget>

Poszczególne węzły oznaczają:

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.