Tag Archives: php

OpenID server on php 5.3

You want to turn your blog into an OpenID server so you can login to sites accepting OpenID with your own OpenID url.One nice advantage of this is that if you're already logged into your blog you don't have to provide a username and password anymore.

The Problem

You install the OpenID plugin, configure it as a server, but you run php 5.3 and the server part of this plugin doesn't work with PHP 5.3.

The Solution

Download my patch ( for OpenId 3.3.2 plugin ) :OpenID Server php 5.3 patch-0.1 (907 bytes)

Copy to wp-content/plugins and run:

patch < openid-server-php.5.3.diff

For the lazy ones here's a version of the OpenID plugin that's already patched: OpenID Server php 5.3 Patched Plugin-3.3.2 - 0.1 (402.61 KB)

Just install it instead of the original plugin.

You want to turn your blog into an OpenID server so you can login to sites accepting OpenID with your own OpenID url.One nice advantage of this is that if you're already logged into your blog you don't have to provide a username and password anymore.

php tail

The Problem

You want the functionality of tail(1) in a php function.

The Solution

Bellow is a php function that gives you the last N lines from a file. It doesn't do everything tail(1) does ( like following, retrying, etc ) but just the basic stuff:

  1. function tail($file, $num_to_get=10)
  2. {
  3. $fp = fopen($file, 'r');
  4. $position = filesize($file);
  5. $chunklen = 4096;
  6. if($position-$chunklen < = 0 )fseek($fp,0);
  7. else fseek($fp, $position-$chunklen);
  8. $data="";$ret="";$lc=0;
  9. while($chunklen > 0)
  10. {
  11. $data = fread($fp, $chunklen);
  12. $dl=strlen($data);
  13. for($i=$dl-1;$i>=0;$i--){
  14. if($data[$i]=="\n"){
  15. if($lc==0 && $ret!="")$lc++;
  16. $lc++;
  17. if($lc>$num_to_get)return $ret;
  18. }
  19. $ret=$data[$i].$ret;
  20. }
  21. if($position-$chunklen < =0 ){
  22. fseek($fp,0);
  23. $chunklen=$chunklen-abs($position-$chunklen);
  24. }else fseek($fp, $position-$chunklen);
  25. $position = $position - $chunklen;
  26. }
  27. fclose($fp);
  28. return $ret;
  29. }

It may not be the fastest solution but it works.
Have a better one? Please let me know about it.

Ask me questions

Have a question about unix, linux, freebsd.  Or maybe you want some advice about configuring apache, mysql,an email server like exim, qmail, postfix, a proxy server like squid cache or antinat, dns or anything else similar. Want some help with php programming or maybe you want to create a wordpress plugin?

Feel free to ask and I'll do my best to answer it on this blog. I will publish a new blog post for each question and my answer.

You can use the contact form or ( if your question is short enough ) you can send it to me over twitter

You can follow me on twitter or subscribe to my RSS feeds if you want to be notified when I post the answer to your question.

Comparing float values in PHP

I had to learn this the hard way. It seems in php 27.64 is just not quite 27.64 , but something close to it ( that's what some people say here anyway: http://www.php.net/ternary ) .

And that's why the following code wouldn't echo the text "dude" as you might think it should:

  1.  
  2. < ?php
  3. function t($amount){
  4. $amountdue=10.00+2.88+2.88+2.88+9.00;
  5.  
  6. echo "amountdue: $amountdue, amount: $amount\n";
  7. if($amountdue == $amount) echo "dude\n";
  8. else echo "but still no match\n";
  9. }
  10. $amount=27.64;
  11. t($amount);
  12. ?>
  13.  

Run this script and you should see:

amountdue: 27.64, amount: 27.64
but still no match

That's the dumbest thing I've ever seen. A similar code written in C gives the good results. Isn't php written in C? They should have copied C's good behavior.
If conversion from float to string gives the right results, why not use the same results when comparing float values?
So if you're having this problem it seems this will work:

  1.  
  2. if((string)$amountdue == (string)$amount) {
  3.  

The fact that php can't compare float values reliably and that you have to resort to this to make it work just makes php look bad.

Adding new php syntax

This is a quick patch I did to php's source code to implement some special syntax. Basically I wanted to be able to define an array like this:

  1. $a=[ 1,2,3,4];

Get the patch here:  New array syntax for php-5.2.6-5.2.9 (997 bytes)
To get this behavior download php's source code, extract it put my patch in the source directory and  do this:

  1. patch -p1 < new_array_zend_syntax.patch
  2. cd Zend
  3. ./buildconf
  4. ./configure
  5. make
  6. cd ..
  7. ./configure
  8. make
  9.  

( This will only compile but not install - in case you want that just type make install at the end )
And here's a test script :

  1. $a=[ 'key' => 'value',1,2,3];
  2. print_r($a);

Save this script as test.php then run sapi/cli/php test.php

This was tested on php 5.2.6 and 5.2.9. I think this is probably useless for most people but it was fun to write so why not share it 🙂

HowTo: Shared Hosting as Socks Proxy

Problem

You need a proxy to connect to a service that would only accept connections from a certain location.

You have a shared hosting account on a server in location that is accepted by the service where you want to connect. Could you use it as a proxy server.?

You could install one of those proxy scripts made in php but that would only let you browse the web, what you want is be able to proxify any application and for that you need a socks server working with one of those proxifier applications  (like tsocks on linux/unix ).

So could you use a socks proxy on your shared hosting account?

Solutions

The solutions are listed starting with the most simple working on the most permissive hosting accounts and ending with the most complex suited for the least permissive accounts.
There will be further posts describing the solutions in detail. This post is mostly an introduction.

  1. SSH Tunnel

    This is the simplest but it assumes that your hosts allows ssh access to your account and they don't block ssh tunnels.

    1. ssh user@hosting-server.com -D1080

    This creates a socks server on your local host , then you can use it in the proxifyer app to forward all connections through it.

  2. Custom SSH Tunnel

    This is a solution for those hosting accounts that don't allow ssh tunneling, but allow you to connect over ssh and run a program ( antinat - a socks server ) once connected over ssh.

    ( One might wonder: why create a tunnel when you could just run antinat and connect directly to it? If you can do that then that's the best way to do it but most shared hosting servers would have all ports blocked so you would not be able to connect to any port other then the standard ones ( 80,443,25,110,143, etc ) but those are only available to root and are already busy anyway. )

    The idea is to forward the traffic from your computer to the proxy server through the actual ssh connection instead of using the standard tunneling mechanisms which are blocked by server's configuration.

    For this you would need a program on your host to act both as a socks server ( sort of ) and as a forwarder through a ssh connection. On the other side ( hosting account ) you would need another program that would receive data from the ssh connection and forward it to antinat. Both programs would actually have to forward data both ways.

    Both forwarders would have to multiplex connections and forward them through a single ssh connection because most hosting accounts only allow one connection / user

  3. Callback Socks server

    This is a solution in case your hosting account has no ssh access.

    It's similar to previous solution but in this case instead of having the local forwarder connect to the remote ( hosting ) forwarder through ssh, you eliminate the remote forwarder and just have the socks server connect back to the local forwarder and then forward everything through that connection.

    This would require modification to the socks server as antinat doesn't have this callback feature built in.

    Another requirement is that you are able to upload and run antinat on the server. Usually you can do this by just calling it in a php script ( eg.: system('antinat') ) or from a perl script if the host offers cgi access.

  4. Custom script ?

    What if for some reason (no cgi or php system() blocked ) you can't run antinat?

    Well in this case I'm guessing it would be possible to write a script that you could call over a http connection, and forward through it, but php's socket functions would need to be available and script's max execution time would limit your connection time so don't expect much of this.

I have used solution #1 and I wrote the software and patches required to make #2 and #3 work. In the following weeks I'll write the posts to describe them in more details.

You can subscribe to my RSS feeds or connect with me on one of the social networks listed in the sidebar if you want to be notified when they are posted.

If you know other ways of doing this or ideas about my solutions I'd love to read about them in the comments.

PHP pecl freebsd port bug

A bug exists in the pecl cli script on freebsd that will not permit you to install any pecl package.

The problem is that the pecl script needs pcre.so but the script calls php with -n ( don't use php.ini ) so the pcre.so extension is not loaded.

A quick fix is to edit /usr/local/bin/pecl and remove "-n" from the last line so it will look like
exec $PHP -C -q $INCARG -d output_buffering=1 -d safe_mode=0 -d register_argc_argv="On" $INCDIR/peclcmd.php "$@"

I found this bug when I wanted to install the svn extension but it seems the bug is known for some time and there is a patch for it : http://www.freebsd.org/cgi/query-pr.cgi?pr=110209