Witam po prawie półrocznej przerwie
!
Dostałem już wolne od szkoły i maturki, która swoją drogą poszła całkiem nieźle, czas na parę nowych wpisów i wieści z frontu
Witam po prawie półrocznej przerwie
!
Dostałem już wolne od szkoły i maturki, która swoją drogą poszła całkiem nieźle, czas na parę nowych wpisów i wieści z frontu
Napisane w Uncategorized
Basically, there is no obvious way to get x and y coordinates of, for example, input element. Why need this? For example to make autocompleter window show always under the given input.
I’m sure that JavaScript frameworks offer this functionality, but when we need slick script adding framework that is 10 times bigger than our software.
Let’s begin then.
Actually we can get element position – relative to it’s parent node, it is stored in offsetLeft and offsetTop properties.
The absolute position is the sum of all relative position, something like relative to root (in this case the BODY element) node position.
Every DOM element has offsetParent property, that is reference to parent object. When we reach the root node offsetParent is null. Therefore using we can build a loop that will sum all postions for us.
function getX(obj){
var x = 0;
while(obj.offsetParent) {
x += obj.offsetLeft;
obj = obj.offsetParent;
}
return x;
}
function getY(obj){
var y = 0;
while(obj.offsetParent) {
y += obj.offsetTop;
obj = obj.offsetParent;
}
return y;
}
Usage:
alert( getY(document.getElementById("element")) );
Simple!
In next post we’ll try to build autocompleter, learning something new and using this functions above…
Napisane w English, Programowanie | Tagi:html, javascript
My task was to add some data to the tables that I did not designed, and there I can’t add some KEYS for me to determine if some rows has the same values in some fields. I’ve been digging through documentation and this is what I’ve came up with;
In MySQL we can add some data using INSERT + SELECT:
INSERT INTO sexy_table (cell1, cell2, cell3) SELECT 'valueForCell1', 'valueForCell2', 'valueForCell3'
If there is no fields in select (known as “rows have gone for a beer”) INSERT will not continue to execute and no error will be thrown.
Now, to have empty SELECT (known as don’t insert anything!) we have to add some logical conditions that will give us FALSE value. But
SELECT 'var1' WHERE 1=2
does not work!
But here a little, tiny, sweet keyword gives us a helping hand: the DUAL keyword.
It will act as dummy table, just to have some compilance withl SQL language. So the statement looks like this:
SELECT 'var1' FROM DUAL WHERE FALSE
Result: no rows, note that 1=2 is equal to FALSE keyword.
Now, non working, but proper, SQL INSERT (who the hell need it?!)
INSERT INTO sexy_table (cell1, cell2, cell3) SELECT 'valueForCell1', 'valueForCell2', 'valueForCell3' FROM DUAL WHERE FALSE
using all of this easy stuff above we can solve our problem: how to chceck if data already exists in DB before inserting.
Assuming that cell1 is the cell that has to be unique:
INSERT INTO sexy_table (cell1, cell2, cell3) SELECT 'valueForCell1', 'valueForCell2', 'valueForCell3' FROM DUAL WHERE NOT EXISTS( SELECT * FROM sexy_table WHERE cell1 = 'valueForCell1')
Easy huh?
The example above shows that many of operations we can do before inserting, just use your invention to boost up your queries!
Napisane w English, Programowanie | Tagi:insert, mysql, optimizations
My IPod Mini has broken few months ago, and one day i’ve digged it out and thought that it would be not that stupid to finally get it working by replacing hard disk that caused problems.
After googling a little i’ve figured that Compact Flash card can be a replacement for Microdrives Apple put in IPods Mini.
Note that CF you’ll try to install in IPod has to support True ATA access mode – before buying check on producer’s webpage for specifications. I used Transcend 133x 8GB CF card to replace old and broken 6GB Hitachi Microdrive.
The eaisiest way is to connect your CF enabled IPod to Windows machine with ITunes, and use “restore” option.
On Linux you’ll have to dd firmware directly to the firmware partition – the corresponding tutorial how to do this you’ll find on rockbox.org
To get Rockbox, the ubiquitous music player firmware, you’ll need 2 things on your IPod: the bootloader and the Rockbox actual firmware.
Rockbox can be installed in normal way, just by unpacking latest build suitable for your device (can be found on http://build.rockbox.org/), or using RockboxUtility
Bootloader is installed by IPodPatcher console program that can be found on http://www.rockbox.org/twiki/bin/view/Main/IpodPatcher , however the image that it contains doesn’t like CF cards, more precisely it soes not recognize partitions that are made on IPod (first ~30MB partition for firmware, rest for stuff). Happily some people made working bootloaders for us, that can be found on:
http://www.rockbox.org/tracker/task/8901?getfile=16426 IPod Mini 1st gen
http://www.rockbox.org/tracker/task/8901?getfile=16980 IPod Mini 2nd gen
Installation goes as described:
[INFO] Scanning disk devices...
[INFO] Ipod found - 2nd Generation Mini ("winpod") - disk device 1
[INFO] Reading partition table from \\.\PhysicalDrive1
[INFO] Sector size is 512 bytes
[INFO] Part Start Sector End Sector Size (MB) Typ
[INFO] 0 63 80324 39.2 Empty (0x00)
[INFO] 1 80325 15662302 7608.4 W95 FAT32 (0x0b)
[INFO] Ipod model: 2nd Generation Mini ("winpod")
[INFO] Checksum OK in bootloader.ipod
[INFO] Reading original firmware...
[INFO] Wrote 3452928 bytes to firmware partition
[INFO] Bootloader bootloader.ipod written to device.
Now unplug your IPod and eventually reboot it using SELECT+MENU, Rockbox should now boot.
W poprzednim poście opisałem czym jest memcache i jak go zainstalować i sprawić żeby PHP mogło się z nim komunikować. W tym poście zajmiemy się tym właściwie czego potrzebujemy: wykorzystaniem memcache do zastosowań praktycznych
Kiedy się tylko da. Ja wykorzystywałem memcache do:
Generalizując memcache nadaje się do przechowywania danych których pobranie z bazy danych/internetu/innych (przecież źródłem danych nie zawsze jest baza!) zajmuje dużo czasu lub są pobierane często podczas odwiedzania strony, i nie są to dane często zmieniające się. Niby oczywistość ale warto o tym wszystkim pamiętać przy decyzji czy memcache czy też nie.
Oczywiście prościej posłużyć się miernikiem czasu który nam zwyczajnie powie co jest szybsze: baza czy memcache; prawie zawsze powie memcache ale trzeba jeszcze brać pod uwagę że zasoby pamięciowe serwera memcached są ograniczone i przechowywanie pełnych wyników wyszukiwania albo całych listingów postów w memcache nie jest zbyt dobrym pomysłem.
Jeżeli chodzi o liczniki – postów, komentarzy etc. – memcache oferuje całkiem wygodne funkcje dekrementacji/inkrementacji o których poniżej.
Na http://pl.php.net/memcache znajduje się pełna dokumentacja API memcache w PHP.
To zadziała na domyślnych ustawieniach
<?php
// Polacz z memcache
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
// Czy NIE ma danych w memcache?
if(! $data = $memcache->get('blog_testarray')) {
// Nie ma danych - zapisujemy nowe do memcache
$data = array(
'time' => time(),
'string' => 'obtained from memcache or not?'
);
$memcache->set('blog_testarray', $data, false, 10);
}
// W tym punkcie mamy obecną zmienną $data
// Albo pobraną z memcache poprzez linijkę
//
// if(! $data = $memcache->get('blog_testarray')) {
//
// Albo zdefiniowaną w linii 11
// Pokaż co dostaliśmy
var_dump($data);
?>
Zauważ, że operacja w linii 8 nie jest porównaniem – to przypisanie do zmiennej $data danych zwróconych przez metodę $memcache->get().
Metoda ta zwróci fałsz jeżeli podanego klucza nie ma w memcache – co odwrócone wykrzyknikiem da nam prawdę; Wtedy całość wyrażenia w ifie jest prawdą.
Opisana powyżej składnia sprawdzania czy dane są w memcache wydała mi się całkiem wygodna i właśnie z niej będziemy w tym poście korzystać. Uogólniając:
<?php
if(! $data = $memcache->get('klucz w memcache - dowolny')) {
// Definicja danych - pobranie z bazy etc etc + zapisanie do memcache
$data = foo(). bar();
$memcache->set('klucz w memcache - dowolny', $data, false, 10 /* Czas ważności keszu */);
}
?>
Dowolną zmienną, którą da się serializować – tablice, stringi etc. Wyjątkiem są zmienne resource – np. link do połączenia z plikiem, handler do pliku zwrócony przez fopen() etc.
Teraz trochę o przechowywaniu obiektów:
Memcache jest idealnym materiałem na singletona.
Tak dla przypomnienia: ordynarnie rzecz ujmując singleton to taki obiekt który jest jeden na cały kod.
Nie ma sensu za każdym razem łączyć się z memcache i o ile chcemy uniknąć zabawy w zmienne globalne lub też w przekazywanie za każdym razem obiektu memcache przez parametr, możemy wykorzystać wzorzec singletona. /* O wzorcach też w sumie możnaby napisać jakiegoś posta, nie? */
Oto całkiem prosty przykład singletona dla Memcache:
<?php
/**
* Memcache sandwitched in The Singleton bread
*
* @author Artek Wiśniewski
* @license BSD
*/
class nsMemcache extends Memcache {
/**
* memcached host
*
*/
const HOST = 'localhost';
/**
* memcached port
*
*/
const PORT = 11211;
/**
* Instance will be held here
*
* @var nsMemcache
*/
private static $_instance;
/**
* Private constructor
* only class itself can make instances of itself
* we are doing this to prevent creating multiple objects of nsMemcache
*
*/
private function __construct() {
$this->automatedConnect();
}
/**
* This method will connect memcache to server using const values defined above.
*
* @throws Exception when connection failed
*/
private function automatedConnect() {
if(! $this->connect(nsMemcache::HOST, nsMemcache::PORT))
throw new Exception('Could not connect to the memcached server');
}
/**
* Return ready and connected nsMemcache object
*
* @return nsMemcache
*/
public static function getInstance() {
// is singleton present?
if(! isset(nsMemcache::$_instance))
nsMemcache::$_instance = new nsMemcache();
// return one and the same object constantly
return nsMemcache::$_instance;
}
}
?>
Mam nadzieję że komuś się przyda
A na wzorce (którem znam i stosowałem) zapraszam do następnego posta…
Aaaaa i bym zapomniał, jak tego używać?
Ustawiamy sobie stałe HOST i PORT, klasę includujemy, i potem w dowolnym miejscu kodu:
<?
$mc = nsMemcache::getInstance();
$val = $mc->get('some_funky_key');
// works like normal Memcache class...
// ...
?>
Napisane w Programowanie | Tagi:memcache, php, singleton
Jak wszyscy wiemy czasem na stronach podajemy dane które wcale nie muszą być aktualne za każdym razem kiedy je serwujemy – tak jest np. ze statystykami ilości ogłoszeń na marketo.pl. Podobnie może być z licznikami, powiedzmy, ilości komentarzy, które wystarczy odświeżać tylko przy ściśle określonych sytuacjach takich jak dodanie/usunięcie komentarza – w ten sposób nie bombardujemy za każdym razem bazy COUNT()’ami.
Memcache jest biblioteką – dokładniej daemonem z interfejsem sieciowym – umożliwiającym nam przechowywanie praktycznie dowolnej wartości pod podanym kluczem (identyfikatorem typu string) w pamięci serwera. Mając dobry hosting możemy sobie zarezerwować np. całe 2-3GB pamięci tylko dla memcache i w ten sposób zbudować stronę szybką niczym jurna dziewica.
Skoro używasz linuxa to sobie poradzisz z instalacją memcached.
Do celów testowych – nie polecam serwerów na windowsie.
Na początek musimy się zaopatrzyć w daemona memcached; gotowe binaria dla windoze można pobrać z:
http://code.jellycan.com/memcached/
Archiwum wypakowujemy w dowolnym miejscu i teraz mamy 2 opcje do wyboru: memcache jako aplikacja i memcache jako usługa systemu windows;
W wypadku opcji pierwszej jedyne co musimy uczynić to kliknąć dwukrotnie na ikonkę memcached.exe – i już
Kiedy chcemy częściej korzystać z memcached do testów naszej strony go wykorzystującej warto go zainstalować jako usługę:

Na tym etapie mamy już działający serwer memcache na adresie 127.0.0.1, porcie 11211.
PHP oferuje rozszerzenie PECL do komunikacji z memcache – php_memcache.dll - jeżeli ta biblioteka znajduje się w katalogu ext twojej instalacji to wystarczy teraz że dodasz (odkomentujesz) w php.ini linijkę
extension=php_memcache.dll
Jeżeli tej biblioteki nie posiadasz to możesz ją pobrać z
http://pecl4win.php.net/ext.php/php_memcache.dll
Teraz restartujemy naszego Apache i dla pewności w phpinfo() możemy sprawdzić czy moduł został załadowany;

Gdyby moduł nie został załadowany można sprawdzić czy nie ma jakiś dodatkowych plików php.ini do wyedytowania (np. w XAMPP jest ich bodajże 6)
Teraz już można bawić memcache w PHP, szczegóły kodowania, wygodne praktyki i przykładowe zastosowania opiszę w następnym poście.
Napisane w Programowanie | Tagi:memcache, memcached, php, windows
Z serii “patrzcie co spłodziłem”:
Marketo.pl jest serwisem łączącym agregator ogłoszeń drobnych z różnych serwisów ogłoszeniowych (olx.pl, marketeo.pl, ale.gratka.pl, gumtree.pl, dwukropek.pl, kupsprzedaj.pl) oraz wyszukiwarkę szperającą w tychże ogłoszeniach.
Nad serwisem pracowałem z Nazinem i popełnienie tegoż oprogramowania zajęło nam koło miesiąca, do jego budowy wykorzystaliśmy nasz framework netSource (hell yeah, do takich zastosowań idealny) działający na PHP5 + hardkorowo wykorzystywaną bazę MySQL 5 (niektóre zapytania przerażają). Oprócz tego mamy podpowiadanie fraz szukania (na razie tylko w zaawansowanych) oparte na mootools. Między linijkami kodu przewija się też memcache. Grafikę wykonał gość z zewnątrz.
Agregacje z innych serwisów wykonuję podframework korzystający z bibliotek netSource (dobrze się złożyło że mieliśmy coś podobnego napisanego już wcześniej) i mnóóóóóóóóóóóóóstwo pregów.
Zapraszam do testów i zgłaszania błędów – których się nie dopatrzyłem, a na pewno gdzieś czekają pod powierzchnią gotowe by uderzyć.
Piszę sobie właśnie pobieranie newsów z różnych stron internetowych, wszystko parsuję sobie za pomocą wygodnych pregów wbudowanych w php. O ile wyciaganie prostych wartości z znaczników HTML nie było problemem i można je zrobić za pomocą wyrażenia
<htmltag>([^<]+)</htmltag> (pobieraj wszystko do znaku “<“)
tak problem się pojawił jak przyszła potrzeba wyciągnięcia jakiejś większej struktury htmlowej, zawierającej child tagi i białe spacje. Krzykniecie lazy dot? No nie do końca, trochę mi to problemów sprawiło, stąd ten post
Przykładowo chcemy do otrzymać wszystko co się znajduje w divie od id “postexcerpt”:
<div id="postexcerpt" class="postbox if-js-closed"> <h3>Excerpt</h3> <label class="hidden" for="excerpt">Excerpt</label><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"></textarea> Excerpts are optional hand-crafted summaries of your content. You can <a href="http://codex.wordpress.org/Template_Tags/the_excerpt" target="_blank">use them in your template</a></div>
Oczywiście można sobie całość przeparsować i dojść do tego co chcemy poprzez DOM, ale zeżre nam to mnóstwo czasu i mocy którą możemy zmarnować gdzie indziej.
Początkowo próbowałem wyrażenia
/<div id=”postexcerpt” class=”postbox if-js-closed”>(?<text>.*?)<\/div>/
Mój wierny towarzysz, .*? , tutaj sobie nie radził, więc zacząłem szukać po necie, dokumentacjach i wyszło na to że problem się rozwiązał po kombinacjach własnych – mianowicie lazy dot nie przewiduje w sobie białych spacji, należy je dołączyć. Powstaje nam wyrażenie
/<div id=”postexcerpt” class=”postbox if-js-closed”>(?<text>(\s|.)*?)<\/div>/
W postaci gotowego kodu php
<?php $newsContent = '
<div id="postexcerpt" class="postbox if-js-closed">
<h3>Excerpt</h3>
<label class="hidden" for="excerpt">Excerpt</label><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"></textarea>
Excerpts are optional hand-crafted summaries of your content. You can <a href="http://codex.wordpress.org/Template_Tags/the_excerpt" target="_blank">use them in your template</a></div>
';
preg_match('/
<div id="postexcerpt" class="postbox if-js-closed">(?<text>(\s|.)*?)<\/div>/', $newsContent, $reg);
var_dump($reg);
?>
który da nam
array(4) {
[0]=>
string(424) "<div id="postexcerpt" class="postbox if-js-closed">
<h3>Excerpt</h3>
<p class="inside">
<label class="hidden" for="excerpt">Excerpt</label><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"></textarea>
Excerpts are optional hand-crafted summaries of your content. You can <a href="http://codex.wordpress.org/Template_Tags/the_excerpt" target="_blank">use them in your template</a>
</p>
</div>"
["text"]=>
string(367) "
<h3>Excerpt</h3>
<p class="inside">
<label class="hidden" for="excerpt">Excerpt</label><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"></textarea>
Excerpts are optional hand-crafted summaries of your content. You can <a href="http://codex.wordpress.org/Template_Tags/the_excerpt" target="_blank">use them in your template</a>
</p>
"
[1]=>
string(367) "
<h3>Excerpt</h3>
<p class="inside">
<label class="hidden" for="excerpt">Excerpt</label><textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt"></textarea>
Excerpts are optional hand-crafted summaries of your content. You can <a href="http://codex.wordpress.org/Template_Tags/the_excerpt" target="_blank">use them in your template</a>
</p>
"
[2]=>
string(1) "
"
}
Minus tego taki że preg nie rozpozna nam struktury drzewiastej i w razie wystąpienia innego diva wewnątrz naszego przeszukiwanego taga to zapytanie się wysypie i nie wyciągnie całego taga. Tutaj dobrym rozwiązaniem mogłoby być explodowanie na poszczególne divy i zliczanie ile jest otwartych i ile zamkniętych, póki co nie miałem z tym do czynienia i nie zanosi się na to
Napisane w Programowanie | Tagi:html, php, preg
Witaj na moim nowym devblogu, do którego mam nadzieję wreszcie coś sensownie popiszę
Czasem się zdarzy mi rozwiązać nietypowy dla mnie problem, może komuś się przyda trochę wiedzy przedstawionej tutaj.
Tak czy inaczej, zapraszam do czytania
Napisane w Uncategorized