Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php.pl Kanał ATOM (tag: php.pl)

Autor wpisu: Athlan, dodany: 11.07.2015 16:21, tagi: php, php.pl

Ioncube Loader Extenion allows to run encoded PHP scripts by Ioncube Encoder.

  • Ioncube Loader Extension – extension which starts witch PHP process that can read and run encoded files. The extension is free.
  • Ioncube Encoder – software that allows encode and obfulscate PHP scripts using license key to decryption.

This tutorial shows how to install Ioncube Loader Extension.

1. Download Ioncube loader extension.

Go to the http://www.ioncube.com/loaders.php url and locate your proper platofrm version.

If you are not shure what platform (x86 or 64-bit, TS or NTS ) you need, just run phpinfo() and read from “System” and “PHP Extension Build”. For example this entry looks like:

System: Linux athlan-VirtualBox 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64

PHP Extension Build: API20121212,NTS

I am using 64-bit platform, NTS (non-thread safe).

So copy proper link and call:

wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz

Extract package

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

Autor wpisu: Athlan, dodany: 18.07.2013 01:41, tagi: php, php.pl, symfony

Context

When you scale a PHP application you have to consider several aspects of runtime environment such us:

  • Bytecode caching (e.x. APC or Zend Optimizer Plus or eAccelerator), more;
  • Reading project files from RAM instead of HDD;
  • Caching and minify static content etc.
  • One additional aspect is storing sessions.

By default, PHP stores sessions in files. There are also several approaches to speed up saving sessions, such us memcached, mapping save_path folder as ramdisc, etc.

In scaling approaches there is important that many worker nodes (with deployed application) runs the same code, round-robin selected or load-ballanced, but have the same space to store sessions, because there is no guarantee in distributes architecture, that next user’s request will be handled by the same node. This implies, that session memory have to be shared between nodes, unfortunately storing these data in local RAM doesn’t meet this requirement.

Redis as PHP Session Handler

One of additional approach to storing sessions in fast-memory is Redis – key-value store. This could be configured as centralized or distributed database.

There is available a Redis session_handler for PHP. To use it:

  1. install Redis first as a service [more]
  2. copy/compile redis.so PHP extension [more information]
  3. register an extension in php.ini configuration file
  4. reconfigure session.save_handler in your php.ini configuration file, or set it directly on runtime by writing for e.x.:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://localhost:6379');
Redis Session Handler in Symfony 2

I am using Symfony 2 framework. Unfortunately, 4th step don’t affects the application. You have to register own SessionHandler in config.yml file:

framework:
    session:
        handler_id: session_handler_redis

This configuration uses new SessionHandler registered ad session_handler_redis Symfony Service (more).

We have to write own SessionHandler in Symfony. I have found the Redis SessionHandler proposed by Andrej Hudec on GitHub (original code here). I have decided to use and improve existing implementation.

Declare new SessionHandler class somewhere in your project:

<?php
 
namespace Fokus\Webapp\CommonBundle\SessionHandler;
 
use \Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
 
/**
 * NativeRedisSessionStorage.
 *
 * Driver for the redis session save hadlers provided by the redis PHP extension.
 *
 * @see https://github.com/nicolasff/phpredis
 *
 * @author Andrej Hudec <pulzarraider@gmail.com>
 * @author Piotr Pelczar <me@athlan.pl>
 */
class NativeRedisSessionHandler extends NativeSessionHandler
{
    /**
     * Constructor.
     *
     * @param string $savePath Path of redis server.
     */
    public function __construct($savePath = "")
    {
        if (!extension_loaded('redis')) {
            throw new \RuntimeException('PHP does not have "redis" session module registered');
        }
 
        if ("" === $savePath) {
            $savePath = ini_get('session.save_path');
        }
 
        if ("" === $savePath) {
            $savePath = "tcp://localhost:6379"; // guess path
        }
 
        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', $savePath);
    }
}

Now, add the entry that declares the class as a Symfony Service in services.yml file:

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

Autor wpisu: Athlan, dodany: 05.07.2013 14:01, tagi: php.pl

Howdy! Recently I have faced the inconvenience that I have to develop parts of application beeing friendly-configurable on Linux and at the same time installing them on Windows is a nightmare.

What to do when do you develop on Windows, but you need the production environment based on Linux and you don’t want to buy server? Install Linux locally on Windows and run server on VirtualBox installed on Windows. The same story concerns the situation, when the production server have a lot of shit dependencies you don’t want to have on your developing environment, even it is Linux.

So how to connect VirtualBox Linux server from Windows?

  1. Download the VirtualBox and Linux distribution you want to install (.iso format will be convinience). I have coised Ubuntu, because of  rapid installation.
  2. Create a new virtual machine for your Linux. More info.
  3. Mount your .iso and install Linux on VirtualBox. Installation is really user-friendly.
  4. Now go to the setting of your virtual machine -> network adapters settings -> and change your network adapter to NAT. More info.
  5. Check if everything is ok, in particular that network adaper on virtual machine obtained the IP address. Just type:
    /sbin/ifconfig

    or:

    /sbin/ifconfig | grep addr

    Note the assigned IP address.

  6. Try to ping your virtual machine from host operating system, where VirtualBox is running:
    ping virtaul_machine_ip_address
  7. If everything is ok, your machines works mutualy. Now, install Open SSH server on your linux. For ubuntu:
    sudo apt-get install openssh-server
  8. Now, you can open the connection on your host device. On windows, you can use Putty for connect to the virtual machine’s command line.

My Ubuntu’s command line from Windows 8. Localy.

linux-windows8

Happy coddin’!

Autor wpisu: Athlan, dodany: 15.01.2011 16:54, tagi: php.pl, mysql, sql

Nie raz, nie dwa mieliśmy sytuację, która wymagała od nas koniunkcji warunków większej ilości danych lub dane te były tekstowe, ale niedługie. Niby nic, klucze załatwiają sprawę, ale sięgając do kodu gry bukmacherskiej, musiałem ją nieco zoptymalizować pod względem częstego wyciągania danych. Baza rozrosła się dość szybko, dlatego niezbędna była lekka modyfikacja jej struktury.

Moim zadaniem było bardzo częste wyciągnięcie ID meczu, który musiał na raz (AND) być zgodny z żądaną datą, nazwą drużyny pierwszej oraz drugiej. Informacji do warunków dostarczał system. Oprócz daty, są to dane tekstowe, więc połączyłem je ze sobą CONCAT i stworzyłem z nich sumę md5. Indeks, po którym baza szukała, był już krótszy od warunków, bo zawierał zawsze 32 znaki. Pierwszym warunkiem koniunkcji zawsze była suma md5 wymienionych wcześniej pól rekordu, nazwałem to suma kontrolna rekordu, potem faktyczna wartość pól, aby w razie zdublowania sumy kontrolnej (czego się nie spodziewamy, bo zakres wariacji jest ogromny, ale dla idei) wybrać prawidłowy rekord. Do tej pory wystarczało…

Gdy baza rozrasta się, problemem staje się wyszukiwanie. O ile suma kontrolna to już krok w stronę optymalizacji, dla >100k rekordów, baza danych potrzebowała co najmniej 0.05 sekundy na zwrócenie wyniku. Postanowiłem dodać odcisk palca sumy kontrolnej. Najlepszym rozwiązaniem okazało się dodanie jednego bajtu, który zrobił magię w bazie danych. Jedno pole TINYINT – 8 bitów, zakres 0-255 bez znaku. Założenia odcisku palca:

  • jest wartością liczbową oraz zajmuje tylko jeden bajt, aby oszczędzić miejsca w rekordach oraz indeksach bazy danych,
  • nie musi być uniwersalny (unikalny), a jedynie grupować odciski palców w mniejsze, a liczniejsze zbiory.

Rozwiązanie, które zastosowałem przy generowanu odcisku palca sumy kontrolnej, również nie jest skomplikowane:

  1. Odcisk palca to suma kolejnych znaków sumy kontrolnej rekordu, gdzie 0 – 9 zachowują swoje wartości, a litery [a-f] przyjmują kolejno [10-15], dokładnie jak w przeliczaniu pojedynczych wyrazów systemu liczbowego o podstawie 16 (HEX) na dziesiętny.
  2. Skoro jest to suma, to wartość minimalna jest dla samych zer, zatem MIN = 0.
  3. Wartość maksymalną można stworzyć podając same maksymalne wartości F, zatem MAX = 480.
  4. 480 mieści się na 9 bitach (min. 2 bajty, zakres 0-65535 bez znaku, tracimy 65055 wartości), dzieląc liczbę przez 2 tracimy unikalność odcisku dwukrotnie, ale zmieścimy się na ośmiu bitach, czyli jednym bajcie – możemy użyć typu TINYINT (zakres 0-255 bez znaku, nasza to 0-240), zatem tracimy tylko 15 niewykorzystanych wartości.

Przeprowadzamy testy naszego rozwiązania.

Stwórzmy przykładową tabelę danych test_md5_index, która będzie przechowywała wartości tekstowe w polach data_content, data_content2, data_content3. Tabela może zawierać pole dodatkowe, ale te trzy będziemy wykorzystywać w naszym wyszukiwaniu. Ważnym jest to, że warunkiem jest koniunkcja (AND), dlatego możemy stworzyć sumę (analogicznie do sumy logicznej) md5 jako odcisk palca tych pól, który zapiszemy w data_sum varchar(32). Dodatkowo stworzymy odcisk palca odcisku palca – jednobajtowe pole data_sum_index TINYINT.

Od razu zakładamy klucz podstawowy na data_id oraz klucz dla zapytania, który będzie go wykorzystywał, czyli szukanie wspólnie po data_sum_index oraz data_sum.

CREATE TABLE test_md5_index (
  data_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  data_sum_index tinyint(1) UNSIGNED NOT NULL,
  data_sum varchar(32) NOT NULL,
  data_contents text NOT NULL,
  data_contents2 text NOT NULL,
  data_contents3 text NOT NULL,
  PRIMARY KEY (data_id),
  KEY data_index (data_sum_index, data_sum)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

Pora stworzyć funkcję, która przeliczy nam nowy, krótszy odcisk palca na podstawie poprzedniego:

CREATE FUNCTION TestIndexChecksum(sSum VARCHAR(32)) RETURNS TINYINT
BEGIN
 
  DECLARE sSumPart VARCHAR(1);
  DECLARE iSumPart TINYINT;
  DECLARE iSum SMALLINT DEFAULT 0;
  DECLARE i INT;
 
  IF (SELECT sSum NOT REGEXP '^([a-z0-9]){32}$') THEN RETURN 0; END IF;
 
  SET i = 1;
 
  WHILE i <= LENGTH(sSum) DO
    SET sSumPart = SUBSTR(sSum, i, 1);
    SET iSumPart = (SELECT (CASE WHEN sSumPart = 'a' THEN 10 WHEN sSumPart = 'b' THEN 11 WHEN sSumPart = 'c' THEN 12 WHEN sSumPart = 'd' THEN 13 WHEN sSumPart = 'e' THEN 14 WHEN sSumPart = 'f' THEN 15 ELSE 0 END));
 
    IF iSumPart = 0 THEN
      SET iSumPart = sSumPart;
    END IF;
 
    SET iSum = iSum + iSumPart;
    SET i = i + 1;
  END WHILE;
 
  RETURN iSum / 2;
END;

Aby przeprowadzać testy, stwórzmy sobie procedurę, która wstawi nam N losowo, jakkolwiek wypełnionych rekordów do bazy danych:

CREATE PROCEDURE TestIndexesPrepareTest(IN i INT)
BEGIN
  TRUNCATE TABLE test_md5_index;
 
  WHILE i > 0 DO
 
    INSERT INTO test_md5_index SET
      data_contents  = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_contents2 = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_contents3 = (SELECT REPLACE(CONCAT(RAND() * 32), ".", "")),
      data_sum = CONCAT(data_contents, data_contents2, data_contents3),
      data_sum_index = TestIndexChecksum(data_sum);
 
    SET i = i - 1;
  END WHILE;
END;

Po wykonaniu CALL TestIndexesPrepareTest(100000) mamy przygotowane małe środowisko testowe.

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

Autor wpisu: Athlan, dodany: 06.03.2009 14:58, tagi: php.pl

Dziś otwarty został sklep.php.pl, którego mały engine miałem okazję pisać. Póki co można w nim nabyć kubek-termos programatora o szczelnym, plastikowym zamknięciu zapobiegającym rozlewaniu się zawartości:

  • Pojemność 400 ml.
  • Nadaje się do spożywania napojów zimnych i gorących.
  • Utrzymuje temperaturę wiele godzin.
  • Dostosowany dla osób prawo i lewo ręcznych.

Cena z przesyłką wynosi 40zł. Mam nadzieję, że z biegiem czasu asortyment znacznie się powiększy. Warto wspomnieć, że z każdym złożonym zamówieniem zasilasz pulę pieniężną przeznaczoną na nagrody w konkursach o 5 zł.

Autor wpisu: Athlan, dodany: 20.06.2008 07:53, tagi: internet, php.pl

Na forum.php.pl zmiana:

Forum Frameworki, które wcześniej znajdowało się w Gotowych rozwiązaniach, zostało przeniesione na forum PHP. Jest to uzasadnione jego rosnącą popularnością i naszą (ekipy php.pl) chęcią zwrócenia uwagi na ten aspekt wiedzy współczesnego programisty.

Możliwe, że niedługo zostanie podpięty mod, który będzie prosił o dodanie tagów (prefixów) do tematu przy zakładaniu wątku, w celu uporządkowania forum. Stworzymy tagi takie jak: [Zend Framework], [Symfony], [Kohana], [CakePHP], [Agavi], itp. Nieistniejące na liście można dopisać: [nazwatagu]. Bardzo użyteczna modyfikacja stworzona przez webdice zaimplementowana jakiś czas temu na forum Przedszkole.

Autor wpisu: Athlan, dodany: 03.12.2007 21:47, tagi: internet, php.pl

Dziś opublikowałem specyfikację usługi dev.php.pl. Zainteresowanych zapraszam na forum.

Warto podkreślić, że Zarząd PHP.pl nie będzie budował usługi sam, tylko z uzytkownikami dostosowywujac się do ich potrzeb.

Po co to wszystko? Forum przegląda masę talentów, które niestety nie mogą się wykazać. Poprzez dołączenie domeny dev otworzymy furtkę tym, którzy nie mieli okazji przedstawić swoich możliwości, a patrząc na niektóre projekty można dostrzec tylko namiastkę umiejętności programowania i co najważniejsze - pomysłowości - naszego community. Dodatkowo wortal php.pl będzie starał się promować najlepsze projekty poprzez wymienienie ich tytułów i innych materiałów na stronie głównej nowopowstałego serwisu.

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.