Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

2011/11/17

How to install GD Extension on EC2

If you're using Amazon EC2 with Amazon Linux AMI, you my find GD Extension is not installed by default. The following are steps to get it installed.
  • check if PHP GD is installed or not by 'rpm -qa | grep php', if you see 'php-gd-5.3.8-3.20.amzn1.i686" or similar, then you are fine and can stop here.
  • If not, then run command, 'sudo yum install php-gd'
  • And restrat apache by 'sudo /etc/init.d/httpd restart'
  • Cheer!

2011/11/07

Set Magic Quotes Runtime is deprecated

I see a lot of error in logs regarding set magic quotes runtime is deprecated on one of my wordpress site running the nginx server. The error is like the following,
2011/11/07 12:02:48 [error] 15798#0: *130087 FastCGI sent in stderr: \"PHP Deprecated:  Function set_magic_quotes_runtime() is deprecated in /var/www/example/content/wp-settings.php on line 32\" while reading response header from upstream, client: 173.13.114.113, server: www.example.com, request: \"GET /news/ HTTP/1.1\", upstream: \"fastcgi://unix:/var/run/www/php.sock:\", host: \"www.example.com\", referrer: \"http://www.example.com/\"
I already turn off Deprecated error in php.ini, but Not sure why it does not stop. The bad thing is that a lot of deprecated errors make the important error message hidden, so I got the fix this. Finally, the solution is edit wp-settings.php on line 32 to
//set_magic_quotes_runtime( 0 );
//110711 - Since this function is depracted as of PHP 5.3, use ini_set('magic_quotes_runtime', 0); instead.
@ini_set( 'magic_quotes_runtime', 0);

Ref: http://php.net/manual/en/function.set-magic-quotes-runtime.php


2011/10/04

Three Steps to Setup SMTP Mail in Debian

Step one

Install Pear (PHP Extension and Application Repository) by the following command,
apt-get install php-pear

Step two

Install Pear Mail Package by the following command,
pear install Mail-1.2.0
Note: the latest version of Mail package at the time I am writing is 1.2.0, check this page for the current version.

Setp three

Install Net_SMTP, which is required to send SMTP mail. You can use the following command to install it.
pear install Net_SMTP

Done!

The following is the script you can use to test,
<?php
include(\"Mail.php\");

function sendmail_smtp($to, $subject, $body){

   $from = \"you@gmail.com\";

   $host = \"ssl://smtp.gmail.com\";
   $port = \"465\";
   $username = \"you@gmail.com\";
   $password = \"yourpass\";

   $headers = array ('From' => $from,
     'To' => $to,
     'Subject' => $subject);
   $smtp = Mail::factory('smtp',
     array ('host' => $host,
       'port' => $port,
       'auth' => true,
       'username' => $username,
       'password' => $password));

   $mail = $smtp->send($to, $headers, $body);

   if (PEAR::isError($mail)) {
      echo(\"<p>\" . $mail->getMessage() . \"</p>\");
   } else {
      echo(\"<p>Message successfully sent!</p>\");
   }

}
?>
Now, you can use Pear SMPT to send mail on any server even your home server without seting up a mail server. Is it cool?

2011/09/30

PHP mail does not work

The OS is linux, and the webserver is apache, and in php.ini file the mail is set as 'sendmail_path = /usr/sbin/sendmail -t -i'. The problem is that php mail() function does not work, although it returns 1 like it's successful. In this case you will not find any help by looking into apache error log. The debugging should start from maillog, which is located at /var/log/ if you are not specify the different loction in the php.ini. I saw the errors like,
delay=00:00:06, xdelay=00:00:02, mailer=relay, pri=120481, relay=*****, dsn=4.5.0, stat=Operating system error
sendmail[24572]: ruleset=try_tls, arg1=mail.***.com, relay=mail.***.com, reject=451 4.3.0 Temporary system failure. Please try again later.
which is actually hard to tell what's going on. I actually tested it mail function thru command line. Accidentally I found if I am root, I was able to send the mail. And I dig more into mail log, I found some useful error logs (note that those logs were generated by the test through url, not command line), like
sendmail[24572]: p8S0pDSY024569: SYSERR(apache): db_map_open: cannot pre-open database /etc/mail/access.db: Permission denied
So then the issue is clear. I checked the /etc/mail/access.db, the mod was 640, so changed to 644, and it sloved the problem.

2011/09/16

Just some note I wrote yesterday

My client wanted to update a webpage with a monthly image, and image extension could be gif, png, jpg, etc. What I need to do is to dynamic check the image in the monthly_tips folder, if there is current month's image, then use it, if not, use the previous month's image, if not, then use a default image.

//get current month, ex: 201109
$ym = date("Ym");

//get last month, ex: 201108
$last_ym = date("Ym",strtotime("-1 months"));

//check if current month's image exists, note that image name like YYYYMM.png, YYYYMM.jpg, etc.
$img = glob("monthly_tips/" . $ym . ".*");
if(count($img) && 0)
  $safty_img = $img[0];
else{//if not found, then check the last month
  $cpath = dirname(__FILE__);
  $img = glob("monthly_tips/" . $last_ym . ".*");
  $default = null;
  //if found the last month's img, then copy it to last.png
  if(count($img)){
    $lastimg = $cpath . "/" . $img[0];
    $path_parts = pathinfo($lastimg);
    $default = 'last.' . $path_parts['extension'];
    $default_path = $cpath . "/monthly_tips/" . $default;
    copy($lastimg, $default_path);
  }
  else{
    $img = glob("monthly_tips/last.*");
    if(count($img))
    $default = $img[0];
  } 
  if($default && file_exists($cpath . "/monthly_tips/" . $default))
    $safty_img = "monthly_tips/" . $default;
  else
    $safty_img = "monthly_tips/default.png"; //worst case;
}

echo $safty_img;


OK, I actually made this way to complicate, and you may not understand what I tried to do here. And my final solution is actually quite simple. The idea is just to use the latest update image in that folder by the following code.

function glob_rsort_latest( $patt ) {
    $rtn = array();
    if ( ( $files = @glob($patt) ) === false ) {
        return $rtn;
    }
    if ( !count($files) ) {
        return $rtn;
    }

    foreach ( $files as $filename ) {
        $rtn[$filename] = filemtime($filename);
    }
    arsort($rtn);
    reset($rtn);
    return $rtn;
}

$files = glob_rsort_latest( 'monthly_tips/*.*' ) ;
if(count($files)){
    $imgs = array_keys($files);
    $safy_img = $imgs[0];
}

2011/07/27

Headache of ISO-8859-1 to UTF8

In Perl, you can use encode ('UTF-8', $iso-text-str) to convert ISO-8859-1 encoded string to UTF-8 encoded string. And in PHP, you can use utf8_encode($iso-text-str) to do the converting.
However, you may be out of luck, for after being converted, some characters could be funky and not what you wanted to see. I think this is because, some characters in UTF8 are invisible, like x80 - x9f (see the following ISO-8859-1 characters list images)





Because I  only care of those regular characters, like \x20-\x7F or \xA9 or \xAE or \x99,  I strip other characters before applying encoding function.
In Perl
$content =~ s/[^(\x20-\x7F|\xA9|\xAE|\x99)]+//g;
$content = encode('utf8', $content);

In PHP
$content = preg_replace('/[^(\x20-\x7F|\xA9|\xAE|\x99|\n)]+/', "", $content);
$content = utf8_encode($content);

UPDATE: Actually, I found that in Perl, encode function cannot correctly convert \x99 to ™. Finally my solution is the following,
open (FILE,  ">$your_file") || die "couldn't write to epcmf file\n";
   binmode(FILE, ":UTF-8");

   $title =~ s/[^(\x20-\x7F|\xA9|\xAE|\x99)]+//g;
   $title =~ s/\x99/™/g;
   $title =~ s/\xAE/®/g;
   $title =~ s/\xA9/©/g;
   print FILE $title;

Note:

  1. You should edit your script in UTF-8, for example, in PUTTY, you can change your character set to UTF-8 at Configuration > Windows > Translation
  2. UTF-8 is different to utf8, so in make sure you write it as binmode(FILE, ":UTF-8");

2011/05/18

Multiple Preg replace in PHP

You can do multiple preg replace with one function call, for example,

PHP, using GeSHi 1.0.8.8
  1. $subject = "{hello}";
  2. $patterns = array("/{/", "/}/");
  3. $replaces = array("{ldelim}", "{rdelim}");
  4. echo preg_replace($patterns, $replaces, $subject); 

Guess what your get? you get,

{ldelim{rdelim}hello{rdelim}

The reason you get this is that perg_replace executes multiple patterns one by one, so ‘{‘ is replaced by ‘{ldelim}’, and then ‘{ldelim}’ is replaced by ‘ {ldelim{rdelim}’.

I believe this is not what you wanted to get. You only want one ‘pattern’ is replaced once. So you can do this,

PHP (brief), using GeSHi 1.0.8.8
  1. $title = "{abdcd}";
  2. $patterns = array("/{/", "/}/");
  3. $replaces = array("LC", "RC");
  4. $title = preg_replace($patterns, $replaces, $title);
  5.  
  6. $patterns = array("/LC/", "/RC/");
  7. $replaces = array("{ldelim}", "{rdelim}");
  8. echo preg_replace($patterns, $replaces, $title);

Finally, you get,

{ldelim}hello{rdelim}

Note that in smarty template, to keep brace, you have to change ‘{ ‘or ‘} ‘to ‘{ldelim}’ or ‘{rdelim}’, or add {literal} and {/literal} around the code that you don’t want smarty engine to interpret it.

2010/07/09

Small php script in Smarty templates

Sometimes, we wanted to run a small PHP scripts inside Smarty templates. That’s good that we don’t need to touch PHP source file to add smarty variables. Here is an example,

In the PHP source code, I have smarty variable named phpvar,

<?php
$phpvar = "Hello World";
$smarty->assign('phpvar', $phpvar);
?>

And in the smarty tempate file, I wanted to split phpvar into tow variable. Sure, you can update source code, to include 2 variables, but sometime, you may do it in the template file. Here is how,

{if preg_match("/(.+)\s+(.+)/", $phpvar, $matches)}
<li>{$matches.1}</li>
<li>{$matches.2}</li>
{/if}

 

2010/04/09

PHP get ip function

A pretty good way to get IP, especially, your site has different servers, i.e. load balancing.

 function get_ip(){
    if (isset($_GET['ip'])) {
       $ip = stripslashes($_GET['ip']);
    } elseif (isset($_SERVER) and !empty($_SERVER)) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } else {
        if (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } else if (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } else {
            $ip = getenv('REMOTE_ADDR');
        }
    }
    return $ip;
}

2010/01/26

informix database using PHP

In a project, I need to write a php code to talk to informix database, which I have not done before.

First, you need PHP Informix Module, here is an guide, http://www.ibm.com/developerworks/data/library/techarticle/dm-0606bombardier/

Fortunately, the server I am working on has already installed this module, so I just wrote a simple test script as the following,

<?php
$conn_id = ifx_connect ("mydb@ol_srv1", "user", "pass");
?>

This code snippet is from PHP Manual, which is actually not a good for test. because if there is some error in ifx_connect, you will not see any error message. I found a better one from PhpDig.net, http://www.phpdig.net/ref/rn30re552.html

if (!$conn = @ifx_connect( "stores7@demo_se", "testuser", "password" )) {
   die( sprintf( "Connection error: %s %s", ifx_error(), ifx_errormsg() ) );
}

I experienced the following error at the beginning,

Connection error: E [SQLSTATE=IX 001  SQLCODE=-1829] Unable to load locale categories.

The guy from IBM had an explanation http://www.iiug.org/forums/ids/index.cgi/noframes/read/3333

OK, some environment parameters missing, $INFORMIXDIR, after fixing this one, I got another one missing:

Connection error: E [SQLSTATE=IX 000  SQLCODE=-25560] Environment variable INFORMIXSERVER must be set.

Finally, fixed!

2009/08/25

PHP4 CLASS VS PHP5

  1. PHP4 classes don't have scope operators such as private, public or
    protected.
  2. PHP4 constructional function should be the same name with that of the class. __construction won't work.
  3. Class variables in PHP4 classes are declared with the keyword 'var' rather
    than private or public.

REF: kavoir.com

2009/07/07

Call Member function

PHP5 is OO language. For a basic usage, we may not need to understand the concept of OO design in details, so sometimes we may forget how to call a member function defined in a Class. :-(

Got this error this morning:

PHP Fatal error:  Call to undefined function get_tokens()

Haha!

The solution:

$this->get_tokens();

Remember to you must have $this-> to call a member function defined in a Class.

2009/06/30

$_SERVER to get current URL

Checked PHP Manual,

$_SERVER is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here.

If you are using apache, check this page,

SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/

In my server, I can use below code to get URL without query string (or ‘?q=’).

$url = getenv("SCRIPT_URI");
//or
$url = $_SERVER['SCRIPT_URI'];

2009/06/25

include library files

If you hosted your site somewhere, your probably wanted to know where the root directory path is, in order to include (or require) some library files, which requires a whole path.

If you hosted on linux system, then it is easy to find it out, by

$docRoot = getenv("DOCUMENT_ROOT");
include ($docRoot . "path/to/yourfile");

However, if you hosted on IIS system, then getenv would not work. Here is a workaround:

require_once(dirname(__FILE__) . '/../includes/utils.php');
require_once(dirname(__FILE__) . '/includes/utils.php');
Note: direname(__FILE__)return the current dir name, so you need to tweak it a bit (for example, ‘..’ means jump up a level) to find out a correct library files.

2009/03/24

iconv_substr() gives "Unknown error"

If Unknown error(0), then most likely it is this issue, iconv_substr() gives "Unknown error" when string length = 1" and it was fixed in PHP5.2, if you are still using PHP5.1, here is a workaround for this bug,

/*Reproduce code:
---------------*/
$s = 'x';
$s = iconv_substr($s, 0, 1, 'UTF-8');
var_dump($s);
/*Expected result:
----------------*/
string(1) "x"
/*Actual result:
--------------*/
bool(false)
//and Notice: iconv_substr() [function.iconv-substr.html]: Unknown error
//(0) in ...
/*A workaround:
-------------*/
$s = 'x';
$s .=" "; //add one more empty character
$s = iconv_substr($s, 0, 1, 'UTF-8');

But if you got Unknown error(12), which is what I got in lucene search engine. Then it is a issue in this thread, but don’t know the solution yet.

2009/03/20

Sessioin stuff

Session cookie lifetime in our server is 864000 sec, so it is 10days not 30minutes as we always assume.

When people logon online account,

  • 1. get billing/shipping info in account_billing/account_shipping table.
  • 2. then check if there is billing/shipping info in the billing/shipping table with the same session_id.
  • 3. if yes in step2, then update it with the one got from step1; if not, then insert with one got from step one if found in the step 1

2009/03/19

Trademark, Copyright, and Register symbols

Trademark, copyright, and register symbols in iso-8895-1 character set cannot be displayed correctly in other character set, for example, urf-8, or even iso-8895-15.

Try this function, which should fix this issue.

function tcr_encode($str) {
   $str = preg_replace("/".chr(153)."/",'&trade;',$str); // trademark
   $str = preg_replace("/".chr(174)."/",'&reg;',$str); // registered tratemark
   $str = preg_replace("/".chr(169)."/",'&copy;',$str); // copyright
   return $str;
}
//change trademark, copyright, and register symbols to html entity
$title = tcr_encode($title);

2009/03/16

Cleaning up/Formatting user input

We use below function to clean up a user input:

function x_site_safe($input,$do_quot=true,$remv_quot=false) {
   $input = preg_replace("/</","",$input);
   $input = preg_replace("/>/","",$input);
   $input = preg_replace("/\(/","",$input);
   $input = preg_replace("/\)/","",$input);
   if ($do_quot)   $input = preg_replace("/\"/","&quot;",$input);
   if ($remv_quot) $input = preg_replace("/\"/","",$input);
   return $input;
}

Usage:
x_site_safe($input) : remove >, <, ( , ), and change " to &quot
x_site_safe($input, false): remove >, <, ( , and )

For example: (combine with stripslashes and trim)

$str = (isset($_GET['v'])) ? stripslashes(trim(x_site_safe($_GET['v'],false))) : "";

2009/02/26

Solutions of database replication failure

MySQL replication allows you to have an exact copy of a database from a master server on another server (slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that both databases are in sync. (instrested in how this being set up, check it out here, http://www.howtoforge.com/mysql_database_replication)
My compare have two web servers, and the replication is turning on. We use below php file to check the replication status.  
$link = mysql_connect('localhost', 'root', 'password')
   or die('Could not connect: ' . mysql_error());
mysql_select_db('production') or
    mail('example@email.com', 'www cannot connect', $message);
$query = 'SHOW SLAVE STATUS';
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$line = mysql_fetch_array($result, MYSQL_ASSOC);
if ( $line["Slave_SQL_Running"]  != "Yes"  or
     $line["Slave_IO_Running"]  != "Yes" ) {
    $message = $line["Last_Error"];
    mail('example@email.com', 'www replication failure', $message);
}
?>
During the development, we created a database on slave DB, and today we were going to move the code to production, so we created a database on master DB. It used the samed name as the same one on slave DB, but having nothing in there. A few minutes later, we got email telling us the repliation failed.
Here is a solution:
On Slave:
1. In phpMyAdmin export the Database (For example, named A)
2. Drop the Database (A)
3. logon mysql, run command: START SLAVE (It would try to rerun the queries)
On Master:
1. Drop the Database (A);
2. Create a Database using different name (B)
On Slave:
Import the Database using the Export file.

2009/02/23

jquery ajax with xml

1. How to generate XML output By default, echo in php sending the text to the browser. So it you try to generate xml output, you have to send the header before xml output to tell teh browser it is xml, like below: header("Content-Type: text/xml; charset=UTF-8"); $smarty->display('cart/popin.tpl'); 2. How to add html code in a xml node To have html in a xml node, you have to use CDATA:

A CDATA section starts with "<![CDATA[" and ends with "]]>":

3. how to use jquery to get XML respond $.ajax({ url: $(this).attr('href'), type: 'GET', dataType: 'xml', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(xml){ // do something with xml //alert('what\'s next'); $('#buynow-result').html($(xml).find('pop').text()); $('#buynow-inform').show('slow'); }