Lessons learned: No wordpress with nginx

Also never accept system administration jobs, because your client will hassle you all night if the rewrite rules doesn’t work.

It all started with a freelance system administration job. It was fairly simple, just move a couple of wordpress websites to a server. Because I am a idealist, I fancied moving websites to nginx, the web server of my choice, instead of apache2. But I didn’t study it well, because WordPress is deeply integrated with apache. Especially permalinks (i.e. rewrites).

But it is OK, instead of using .htaccess files, you can define rewrite in nginx configuration files, roughly like following:

 

location / {
try_files $uri $uri/ /index.php?$args;
}

This will redirect requests to index.php with certain args, so permalinks will not break.

But what about the sub folders? Your client might have separate wordpress installations on subfolders. This was the part that I’ve missed. Sadly, it caused my client called me number of times during the late evening, and it frustrated me. As a side note, one should really try to learn how to send emails.

Anyways, solution is simple. At least mine was. And I admit that it’s not a good solution, rather it feels like a hack. Just copy the rewrite rule for the subfolder.


location /subwordpress {
try_files $uri $uri/ /subwordpress/index.php?$args;
}

If I had to use wordpress again, I will never use nginx. I will just stick with apache, where guys at WordPress prefer.

my experience with ispconfig

excellent tutorial

http://www.howtoforge.com/perfect-server-ubuntu-13.04-nginx-bind-dovecot-ispconfig-3-p5

Zend Framework 2 comparison

I’ve been using Zend Framework 1.x for quite a long time. It is a stable framework with a lot of features. But I always have some performance issues in terms of memory/cpu usage and page load time. I have looked at the new version of Zend Framework which is under active development. As my first impressions, I have astonished by their new design. Removing require_once statements, using namespaces and lazy loading of components should boost the performance drastically. In addition, the new module system will be very flexible especially for 3rd party component developers.

To see it in action, I have decided to do a quick benchmark. I have used the zf2 skeleton application, and my current zend framework 1.11 setting which I use in any of my PHP projects. The comparison is totally subjective and the aim is to have an overall impression.

I have used the apache benchmarking tool. The number of requests are 100 and the concurrency level is 5.
ab -c 5 -n 100 http://myUrl

Here are the results

Zend Framework 2

Server Software: Apache/2.2.20
Server Hostname: localhost
Server Port: 80

Document Path: /zf2-sample/public
Document Length: 351 bytes

Concurrency Level: 5
Time taken for tests: 0.214 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Non-2xx responses: 100
Total transferred: 61900 bytes
HTML transferred: 35100 bytes
Requests per second: 466.58 [#/sec] (mean)
Time per request: 10.716 [ms] (mean)
Time per request: 2.143 [ms] (mean, across all concurrent requests)
Transfer rate: 282.04 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 10 6.3 11 33
Processing: 0 1 2.6 0 15
Waiting: 0 0 2.6 0 15
Total: 1 11 6.1 11 33

Percentage of the requests served within a certain time (ms)
50% 11
66% 12
75% 13
80% 14
90% 16
95% 23
98% 32
99% 33
100% 33 (longest request)

Zend Framework 1.11


Server Software: Apache/2.2.20
Server Hostname: localhost
Server Port: 80

Document Path: /ad
Document Length: 336 bytes

Concurrency Level: 5
Time taken for tests: 0.410 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Non-2xx responses: 100
Total transferred: 58900 bytes
HTML transferred: 33600 bytes
Requests per second: 243.98 [#/sec] (mean)
Time per request: 20.494 [ms] (mean)
Time per request: 4.099 [ms] (mean, across all concurrent requests)
Transfer rate: 140.33 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 20 14.7 16 53
Processing: 0 1 3.6 0 28
Waiting: 0 1 3.5 0 28
Total: 1 20 14.4 17 53

Percentage of the requests served within a certain time (ms)
50% 17
66% 29
75% 33
80% 34
90% 40
95% 46
98% 51
99% 53
100% 53 (longest request)

Conclusion: New version of Zend Framework is nearly double times faster that the current version.

Getting PHP headers without apache mod headers

It sometimes happen. You are in a restricted environment -like a shared hosting- and somehow you want to reach the custom headers without enabling the apache module “mod_headers”. Than following little function will do your job.

function getHeaders()
    {
        $headers = array();
        foreach ($_SERVER as $k => $v)
        {
            if (substr($k, 0, 5) == "HTTP_")
            {
                $k = str_replace('_', ' ', substr($k, 5));
                $k = str_replace(' ', '_', strtolower($k));
                $headers[$k] = $v;
            }
        }
        return $headers;
    }

P.S. If you have the possibility to use the mod_headers, than you’re free to use apache_get_headers() function.

Think beyond DB

I found a good presentation by the project lead of Zend Framework. He explains the data persistance and why good OO programming instead of refactoring is saves a lot of time.

Zend Framework’da bir Bug

Call to undefined method Zend_View_Helper_Placeholder_Container::ksort()

Bu hatayı zend framework bir şekilde veriyor. Sanıyorum bir bug’dan kaynaklanıyor bu sorun. Yeni versionlarda bu hata giderilmiş olması lazım.  Lakin en kolay (geçici çözüm) ise aşağıdaki metodu Zend/View/Helper/Placeholder/Container/Abstract.php dosyasına eklemek.

Oh yeah.

/**
* Sort the array by key
*
* @return array
*/

public function ksort()
{
$items = $this->getArrayCopy();
return ksort($items);
}

Htaccess dosyası

Htaccess dosyasında kullandığım tanımlamaları sürekli unutuyorum. Burayı da not defteri gibi kullanmaya başladım. Yaptığım olay sırayla şu: Öncelikle uygulama ortamını belirliyorum. Buradaki ortama göre bir config dosyası yüklüyorum çünkü. Sonra optimizasyon için ETag ları set ediyorum. Sora Expire header’ları ayarılıyorum. Sonra her bişeyi Gzip ile sıkıştırıyorum (apache deflate mod sağolsun). Daha sonrası da klasik url rewrite

SetEnv APPLICATION_ENV production

Header unset ETag
FileETag None
Header set Expires "Thu, 15 Apr 2012 20:00:00 GMT"
Header unset Last-Modified

# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

Php Configure command doesnot work on mac osx with intel arch

I have wanted to run my php extensions that I’ve wrote earlier in a linux machine on mac os x snow leopard, but the intel architecture came with the snow leopard does not allow me to that. Basically my extensions are written in 32 bit but my development environment is in 64bits now. By the way I am using Zend Server CE for now.

Normally you should build php for your new extension by running the following commands

phpize
./configure (add some configuration parameters here)
make

But it won’t help and gives an error like this:

mach-o, but wrong architecture in Unknown on line 0

The solution is to add some extra build parameters before the configuration command:

MACOSX_DEPLOYMENT_TARGET=10.6 CFLAGS=’-O3 -fno-common -arch i386 -arch x86_64′ LDFLAGS=’-O3 -arch i386 -arch x86_64′ CXXFLAGS=’-O3 -fno-common -arch i386 -arch x86_64′ ./configure

Then you’re ready to go.

Scalability in PHP

PHP nin sevdiğim tarafı iyi scale edilebiliyor olması. Bu konuda güzel bi prezentasyon buldum.

Shared Hosting için Zend Framework kurulumu

dertli bir iş. en büyük sıkıntı da shared hostinglerde document root değiştirilemediği için oluyor. zend framework için önerilen dizin yapısında public klasörü rootda yer almıyor. bu bir çok açıdan tercih edilmesi gereken bir durum. ancak shared hostinglerdeki document root olan httpdocs ya da public_html klasörünün bir üzerinde değişiklik yapılamadığı için aşağıdaki kodu root dizindeki .htaccess dosyasının içine kopyalayın. public dizinindeki .htaccess dosyasını da kaldırın. mis gibi.

RewriteEngine On

RewriteRule ^\.htaccess$ - [F]

RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]

RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1

RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]

RewriteRule ^public/.*$ /public/index.php [NC,L]

kaynak: şurası.