<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP &#8211; Strona Szoguna</title>
	<atom:link href="https://szogun1987.pl/show/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://szogun1987.pl</link>
	<description>Jeszcze wstawię tutaj jakiś głęboki cytat</description>
	<lastBuildDate>Fri, 04 Mar 2011 23:00:00 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.3.2</generator>
	<item>
		<title>Komunikacja PHP i C Sharp</title>
		<link>https://szogun1987.pl/show/komunikacja-php-i-c-sharp/12/</link>
					<comments>https://szogun1987.pl/show/komunikacja-php-i-c-sharp/12/#comments</comments>
		
		<dc:creator><![CDATA[szogun1987]]></dc:creator>
		<pubDate>Fri, 04 Mar 2011 23:00:00 +0000</pubDate>
				<category><![CDATA[C Sharp]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programowanie]]></category>
		<guid isPermaLink="false">https://szogun1987.pl/?p=12</guid>

					<description><![CDATA[Ostatnio musiałem napisać aplikację w której aplikacja .Net współpracuje z aplikacją napisaną w PHP za pośrednictwem gołego http.
Sprawa nie jest szczególnie złożona jednak jak]]></description>
										<content:encoded><![CDATA[<p>Ostatnio musiałem napisać aplikację w kt&oacute;rej aplikacja .Net wsp&oacute;łpracuje z aplikacją napisaną w PHP za pośrednictwem gołego http.</p>
<p>Sprawa nie jest szczeg&oacute;lnie złożona jednak jak się p&oacute;źniej okazało nie jest taka prosta jak myślałem. Fragmenty kodu zawarte w Blogu pochodzą z przykładowego programu dostępnego do pobrania na końcu postu.</p>
</p>
<p>To co było proste:</p>
<p>Komunikacja PHP z dowolną inną platformą odbywa się za pomocą protokołu HTTP kt&oacute;ry jest og&oacute;lnie dobrze opisany np. <a href="http://www.jmarshall.com/easy/http/" target="_blank">tutaj</a>. Dodatkowo w większości platform istnieją dedykowane biblioteki obsługujące w mniejszym lub większym stopniu komunikację przez http, a biblioteka standardowa .Net nie jest pod tym względem wyjątkiem(tfu!).</p>
<p>Komunikację za pomocą http ułatwiają przynajmniej dwie klasy HttpWebRequest i WebClient. Klasa WebClient ma w moim mniemaniu znacznie bardziej intuicyjny interfejs i to jej będę się starał używać.</p>
</p>
<p>Wywołanie GET:</p>
<p>Wywołanie GET jest odwołaniem się do strony www r&oacute;wnoważnym z wpisaniem adresu w przeglądarce internetowej, parametry do serwera wysyła się dopisując po adresie strony znak zapytania i wartości tych parametr&oacute;w w formacie parametr1=wartosc1&amp;parametr2=wartosc2&amp;parametr3=wartosc3. Ograniczeniem tej metody jest fakt iż długość adresu strony wraz z wartościami parametr&oacute;w nie może przekraczać 256znak&oacute;w.</p>
<p>Metody tej nie powinno się także stosować na stronach w celu przekazywania danych wrażliwych (jak np. login i hasło użytkownika).</p>
</p>
<p>Do zbudowania łańcucha połączeniowego można użyć klasy UriBuilder, jest to klasa kt&oacute;ra na podstawie fragment&oacute;w adresu potrafi złożyć pełną ścieżkę do pliku/katalogu także na serwerze www.</p>
</p>
<p>Klasą kt&oacute;ra się przydaje jest także HttpUtility posiadająca metodę UrlEncode zwalniającą programistę z wstawiania odpowiednich znak&oacute;w ucieczki w wysyłanym zapytaniu do serwera, niestety klasa ta znajduje się w przestrzeni nazw System.Web w bibliotece o tej samej nazwie, biblioteka ta zaś nie znajduje się w Wersji Client Profile platformy .Net. Tak więc jeżeli klasy tej chcemy użyć w projekcie Windows Forms lub WPF musimy dokonać następujących zmian w projekcie:</p>
<p>1) Zapisanie wszystkich niezapisanych plik&oacute;w.</p>
<p>2) W Solution Explorze klikamy prawym przyciskiem myszy na projekt i wybieramy Properties</p>
<p>3) W zakładce Application znajdujemy Combobox Target platform i wybieramy w nim .Net Framework 4.0</p>
<p>4) Zapisujemy wszysto i zamykamy właściwości projektu</p>
<p>5) Klikamy prawym przyciskiem w katalog refereces w projekcie i wybieramy AddReference</p>
<p>6) Przechodzimy na zakładkę .Net i wybieramy System.Web</p>
<p>7) Zatwierdzamy dialog i możemy używać klasy System.Web.HttpUtility</p>
</p>
<p>Najprostszy kod pobierający treść strony www może wyglądać tak.</p>
</p>
<div class="code">
<pre class="prettyprint lang-cs">
WebClient client = new WebClient();
// Przy niekt&oacute;rych serwerach aplikacja powinna się przedstawić 
//client.Headers.Add(&quot;user-agent&quot;, &quot;PHP and dotNet&quot;);

UriBuilder queryBuilder = new UriBuilder(tbServer.Text + &quot;helloGet.php&quot;);
queryBuilder.Query = string.Format(&quot;name={0}&quot;, HttpUtility.UrlEncode(tbName.Text));

string result = client.DownloadString(queryBuilder.Uri);
MessageBox.Show(this, result);
</pre>
</div>
</p>
<p>plik helloGet.php zawiera chyba najprostrzą możliwą obsługę zapytania GET:</p>
<div class="code">
<pre class="prettyprint lang-php">
&lt;?php
echo &#039;Witaj &#039;.$_GET[&#039;name&#039;];
?&gt;
</pre>
</div>
</p>
<p>Pobranie plik&oacute;w z serwera:</p>
<p>Zadanie trochę mniej związane z PHP, aczkolwiek pojawiające się w pracy z http to pobranie pliku z serwera http. Tutaj klasa WebClient oferuje dwie możliwości.</p>
<p>Metoda DownloadFile podaje się adres pliku i nazwę pliku nic prostszego</p>
<div class="code">
<pre class="prettyprint lang-cs">
using (SaveFileDialog sfd = new SaveFileDialog())
{
    sfd.Filter = &quot;Pliki jpeg|*.jpg&quot;;
    if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        WebClient client = new WebClient();
        client.DownloadFile(&quot;http://www.programy.witraze-plocin.pl/wp-content/uploads/2010/04/cycki226jo5.jpg&quot;, sfd.FileName);
    }
}
</pre>
</div>
<p>Metoda DownloadData zwraca tablicę bajt&oacute;w składających się na plik metoda może być przydatna gdy pobrane dane chcemy tylko obrobić bez zapisywania ich na dysku. Np. wyświetlić obrazek w pictureBoxie.</p>
<div class="code">
<pre class="prettyprint lang-cs">
WebClient client = new WebClient();
byte[] buffer = client.DownloadData(&quot;http://www.programy.witraze-plocin.pl/wp-content/uploads/2010/04/cycki226jo5.jpg&quot;);

MemoryStream stream = new MemoryStream(buffer);

// Kwestie techniczne
if (pbCycki.Image != null)
{
    Image oldImage = pbCycki.Image;
    pbCycki.Image = null;
    oldImage.Dispose();
}

pbCycki.Image = Image.FromStream(stream);
</pre>
</div>
</p>
<p>Wadą tej metody jest spore zajęcie pamięci ponieważ cały plik jest wgrywany do RAMu, dodatkowo aplikacja musi pobrać cały plik i dopiero wtedy go obrobić. Przypadkiem gdy żadna z powyższych metod nie zastosowania jest pobranie dużego pliku z serwera i zapisanie go do strumienia nie będącego plikiem(np. wysłać portem COM do jakiegoś urządzenia). W tym przypadku należy wykorzystać metodę WebRequest.</p>
<div class="code">
<pre class="prettyprint lang-cs">
private void FromHttpToStream(Stream outStream, string url)
{
    WebClient client = new WebClient();
    client.OpenRead(url).CopyTo(outStream);
}
</pre>
</div>
<p>Wywołanie POST:</p>
<p>Wysłanie zapytania POST do serwera http przy pomocy klasy HttpClient jest dosyć niskopoziomowe. Ponieważ należy wykonać następujące kroki:</p>
<p>1) Dodać do nagł&oacute;wka wiadomości informację o rodzaju przesyłanej treści &quot;content-type: application/x-www-form-urlencoded&quot;</p>
<p>2) Sformatować treść wysyłanej wiadomości przy UrlEncode</p>
<p>3) Zakodować informację przy pomocy kodowania ASCII i wysłać na serwer.</p>
<p>4) Rozkodować przesłaną wiadomość przy pomocy kodowania użytego na stronie.</p>
</p>
<div class="code">
<pre class="prettyprint lang-cs">
WebClient client = new WebClient();
// Przy niekt&oacute;rych serwerach aplikacja powinna się przedstawić 
//client.Headers.Add(&quot;user-agent&quot;, &quot;PHP and dotNet&quot;);

client.Headers.Add(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);

byte[] buffer = Encoding.ASCII.GetBytes(string.Format(&quot;name={0}&quot;, HttpUtility.UrlEncode(tbName.Text)));
buffer = client.UploadData(tbServer.Text + &quot;helloPost.php&quot;, &quot;POST&quot;, buffer);
string result = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
MessageBox.Show(this, result);
</pre>
</div>
</p>
<p>Upload plik&oacute;w:</p>
<p>Upload plik&oacute;w też jest dość prosty klasa WebClient posiada metodę UploadFile, kt&oacute;ra jako parametry pobiera nazwę wysyłanego pliku i adres pliku do kt&oacute;rego wysyłana jest zawartość pliku.</p>
<div class="code">
<pre class="prettyprint lang-cs">
using (OpenFileDialog ofd = new OpenFileDialog())
{
    ofd.Filter = &quot;Pliki jpeg|*jpg&quot;;
    if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        WebClient client = new WebClient();
        client.UploadFile(tbServer.Text + &quot;uploadFile.php&quot;, ofd.FileName);
    }
}
</pre>
</div>
<p>Po stronie serwera wysyłany plik jest opisany w tabeli $_FILES w polu &#039;file&#039; obsługa pliku. Przykładowa obsługa może wyglądać następująco:</p>
<div class="code">
<pre class="prettyprint lang-php">
&lt;?php
$tempFile = $_FILES[&#039;file&#039;][&#039;tmp_name&#039;];
copy($tempFile, &#039;uploaded.jpg&#039;);
unlink($tempFile);
?&gt;
</pre>
</div>
<p>Pliki z kodem przykładowego programu są do pobrania <a href="/pictures/phpnet.rar" target="_blank">tutaj</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://szogun1987.pl/show/komunikacja-php-i-c-sharp/12/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>PHP Cast patern</title>
		<link>https://szogun1987.pl/show/php-cast-patern/5/</link>
					<comments>https://szogun1987.pl/show/php-cast-patern/5/#comments</comments>
		
		<dc:creator><![CDATA[szogun1987]]></dc:creator>
		<pubDate>Fri, 17 Sep 2010 22:00:00 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Wzorce projektowe]]></category>
		<guid isPermaLink="false">https://szogun1987.pl/?p=5</guid>

					<description><![CDATA[Podczas prac w PHP(z którego na szczęście rzadko korzystam) bardzo wkurza mnie fakt iż nie jestem w stanie zdefiniować (przy pomocy PHP Doca) iż jakaś funkcja zwraca tablicę element?]]></description>
										<content:encoded><![CDATA[<p>Podczas prac w PHP(z kt&oacute;rego na szczęście rzadko korzystam) bardzo wkurza mnie fakt iż nie jestem w stanie zdefiniować (przy pomocy PHP Doca) iż jakaś funkcja zwraca tablicę element&oacute;w określonego typu. Przez co chcąc prze-iterować po wyniku takiej funkcji mam lekko utrudniony dostęp do p&oacute;l i metod danej klasy (uzupełnianie kodu Eclipse nie radzi sobie z taką sytuacją zupełnie). Dlatego jakiś czas temu wpadłem na pomysł dodawania do każdej (a właściwie prawie każdej) nowej klasy statycznej metody Cast:</p>
<div class="code">
<pre class="prettyprint lang-php">class&nbsp;Moja {

	/**
	 * 
	 * Pseudorzutowanie na typ
	 * @param mixed $item
	 * @return Moja
	 */
	public static function Cast($item) {
		return $item;
	}

	public function JakasFunkcja() {
		;
	}	
}
</pre>
</div>
<p>Teraz mogę sobie w kodzie spokojnie zwracać wyniku typu tablicowego i iterować po nim:</p>
<p><img decoding="async" src="http://static.szogun1987.pl/pictures/Code.jpg" alt="pictures/Code.jpg"/></p>
<p>W tej chwili jedyną wadą tego rozwiązania jaka mi przychodzi do głowy jest dodatkowa ilość generowanego kodu.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://szogun1987.pl/show/php-cast-patern/5/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Nowa wersja bloga</title>
		<link>https://szogun1987.pl/show/nowa-wersja-bloga/4/</link>
		
		<dc:creator><![CDATA[szogun1987]]></dc:creator>
		<pubDate>Fri, 10 Sep 2010 22:00:00 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Recaptchia]]></category>
		<guid isPermaLink="false">https://szogun1987.pl/?p=4</guid>

					<description><![CDATA[Korzystając z okazji przymusowego nieróbstwa związanego ze zwolnieniem lekarskim postanowiłem dokończyć pracę nad Blogiem.
A że nie chciało mi się bawić z instalacją Flex Builde]]></description>
										<content:encoded><![CDATA[<p>Korzystając z okazji przymusowego nier&oacute;bstwa związanego ze zwolnieniem lekarskim postanowiłem dokończyć pracę nad Blogiem.</p>
<p>A że nie chciało mi się bawić z instalacją Flex Builder&#039;a na Ubuntu przepisałem całość na &quot;gołego&quot; PHP&#039;a.</p>
<p>W czasie prac nad nowym wyglądem postanowiłem zastąpić swoją bardzo niedoskonałą Captchę zabawką ze stajni Googla noszącym nazwę &quot;ReCaptchia&quot;. Jest to rozwiązanie darmowe, bardzo skuteczne(większość udanych masowych łamań tego systemu opiera się na pracy Hindus&oacute;w) , posiada wsparcie dla os&oacute;b niewidomych, a na dodatek (jak mi się zdawało) jest łatwe w instalacji na każdej stronie.</p>
<p>O ile z wyświetleniem dialogu nie było większych problem&oacute;w:</p>
<div class="code">
<pre class="brush:">echo recaptcha_get_html($publicKey);</pre>
</div>
<p>O tyle weryfikacja poprawności wprowadzonego obrazka okazała się znacznie trudniejsza ponieważ standardowe wywołanie:</p>
<div class="code">
<pre class="prettyprint lang-php">$resp = recaptcha_check_answer ($privateKey,
                                $_SERVER[&quot;REMOTE_ADDR&quot;],
                                $_POST[&quot;recaptcha_challenge_field&quot;],
                                $_POST[&quot;recaptcha_response_field&quot;]);
if($resp-&gt;is_valid)
{
    //TODO: Obsługa zapisu
} else {
    // TODO: Wyświetlić komunikat o błędzie
}</pre>
</div>
<p>Sprawiała że moja strona kończyła się komunikatem &#039;Could not open socket&#039;.</p>
<p>Po dłuższym śledztwie okazało się że komunikat ten pojawia się wielu użytkownikom a błąd z nim związany jest nierozwiązany od dw&oacute;ch lat <a href="http://code.google.com/p/recaptcha/issues/detail?id=26" target="_blank">link</a>.</p>
<p>Jest on bardzo często spowodowany blokowaniem przez firmy hostujące połączeń wychodzących na port 80. Ponieważ walka z OVH o otwarcie portu wydała mi się nie do wygrania (Błąd fsockopen Connection refused jest dość częsty na stronach hostowanych przez tą firmę &#8211; wystarczy wpisać ten komunikat w google) postanowiłem poszukać obejścia, kt&oacute;rym okazały się być serwery Proxy, kt&oacute;re przekierowują połączenie z jednego portu na inny port innego serwera.</p>
<p>Recaptchia nie wspiera Proxy na szczęście biblioteka PHP kt&oacute;ra zapewnia dostęp do Recaptchia jest w pełni Open Source&#039;owa więc otworzyłem ją sobie i zmieniłem metodę _recaptcha_http_post dodając jej parametry $proxyHost = null i $proxyPort = null do kt&oacute;rych można przekazać adres i port serwera proxy. Oczywiście musiałem zmodyfikować też ciało funkcji dodając kod modyfikujący treść zapytania HTTP, oraz musiałem zmodyfikować funkcję recaptcha_check_answer tak aby mogła przekazać informacje na temat proxy do ww. metody.</p>
<p>Ostatecznie kod sprawdzający poprawność tekstu z obrazka wygląda następująco:</p>
<div class="code">
<pre class="prettyprint lang-php">$resp = recaptcha_check_answer ($privateKey,
                                $_SERVER[&quot;REMOTE_ADDR&quot;],
                                $_POST[&quot;recaptcha_challenge_field&quot;],
                                $_POST[&quot;recaptcha_response_field&quot;],
                                array(),
                                &#039;190.90.128.233&#039;, #adres serwera proxy
                                8080);</pre>
</div>
<p>Moje zmiany w bibliotece są wysłane do googla jako załącznik do <a href="http://code.google.com/p/recaptcha/issues/detail?id=80" target="_blank">Zadania nr 80</a> w projekcie Recaptcha mam nadzieję że zostaną włączone do oficjalnej wersji tej biblioteki.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
