Posts Tagged ‘PHP’

.htaccess maintenance

Wednesday, April 13th, 2011

Again a while since the last post but honestly I have a lot of work to do, fortunately one of the projects I’m involved requires me to learn Python.. at last!

Anyway, one division of the company hired a third party to develop a web page. The provider finished the development and finally sent everything to us. It was a php webpage, it uses the Cake Framework and MySQL so everyone thought it was going to be very easy to release the webpage in the company’s server.

A few weeks before today we decided to order the site folder and create special boxes for mini sites and small projects, even though url may seem as if the folder is directly under the web server root, it isn’t. This is cool because it keeps things from being a mess and maintenance becomes pretty easy.

So, as I was saying, we got the scripts for both the site and the database. Database was easy, we just imported the sql file and voilá! done!

The problem rised when we got to the site’s scripts. We typed the url correctly and ¡nothing! so we were surprised, everything was working fine so it wasn’t possible for a single site not to work. We read the logs, enabled the debug and nothing raised. After a few days we decided that the provider should help us. So he happily agreed to bring his people to help me…. same result. Something strange was happening, finally the provider quit and told us that the development was working on their servers and they were happy with that…. sorry :s

I got mad because of this but my boss and I decided we should dig this in. After a few days we found the cause of the problem. When we ordered the web server folders we enabled an alias to a folder. Cake uses htaccess files to provide MVC functionality. When we enabled the alias folder we forgot to enable htaccess parse, duh! so we learned that each directory that will be included on a web server should have a conf line like this:

<Directory /absolute/path/to/alias/folder>
Options -Indexes Includes FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>

We added the proper lines, modified the htaccess rewrite rules to support 2 different domains and now everything works.

We keep learning everyday 😀

Ad Vitam Paramus

Zend Framework 101

Tuesday, February 8th, 2011

Ok, it’s being a while since I last published something here.

I’ve been digging into Zend Framework trying to understand everything so I can code easily. So far I’ve discovered that way too many PHP programmers get confused about three basic definitions.

Zend Framework

As stated before, Zend Framework is a library with a bunch of classes for almost everything (Auth, ACL, DB connections, etc.) this is important, cause I’ve noticed that way too many PHP programmers are confused with ZF being a new way of coding and setting up your application.

With pure Zend Framework you may use any class you want whenever you want to use it, just be sure to include the ZF library path and you’re done.

MVC

Now, while reading about ZF programmers may found a lot of talk about MVC, this stands for Model-View-Controller which is a coding paradigm I won’t explain cause there’s a lot of info about it in the web (Google it).

Here is where you start dealing with the bootstrap, configuration file, error handling and main setups.

ZF Tool

This stands for Zend Framework tool which basically is a bat/bash script that you may use from the command line to automatize some coding if you’re using Zend Framework and MVC. It’s pretty useful and you have the possibility to modify/enhance this script as you wish. If you won’t be coding with MVC you might as well forget about this tool.

Having these three basic definitions we can start discussing the framework. ZF, as I already stated, has a bunch of useful classes which are very simple to use. I know some of you will raise your voice and argue that it isn’t and that you have to place code in the bootstrap and then make a later call in a model and it might become confusing, if so let me remind you that right now I’m just writing about the ZF not being used within a MVC coding paradigm. By this I’m trying to make you understand that ZF can be used to code applications as you being doing for years as long as you are used to OOP.

Let’s see an example of how ZF helps you code faster. I’ll do a simple auth script.

I wont be pasting any HTML or javascript code, I’m assuming you can figure those out.

So, suppose you have a form that sends the login and password to dologin.php, in the php file you’ll have something like this:

<?php
/***********
Include's, require's, session's code.
**********/
/* After receiving, validating and filtering your input you'll define where do the user credentials are stored */
$login = $_REQUEST['login'];
$password = $_REQUEST['pass'];
//Create a database adapter
$dbAdapter = Zend_Db_Table_Abstract::getDefaultAdapter();
//Create the auth adapter
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
//Configure the auth adapter with the proper table name and credential fields.
$authAdapter->setTablename('users')
->setIdentityColumn('login')
->setCredentialColumn('password');
//Give the auth object the info to validate
$authAdapter->setIdentity($login)
->setCredential($password);
//Call the auth instance
$auth = Zend_Auth::getInstance();
//Validate
$result = $auth->authenticate($authAdapter);
//Some code to process the response
if(!$result){
//Go to login, credentials are wrong
}
else{
//Store identity
//Get user data, but avoid retrieving the password
$userData = $authAdapter->getResultRowObject(null,'password');
//Write data to auth object so object is modified
$auth->getStorage()->write($userData);
}
//Do more stuff
?>

So that’s it for the login. It’s pretty simple, and you can make it even more complex by adding some constraints, for example a user row that indicates if that user has been deactivated (Play with it and read the ZF documentation regarding this).

Now let’s say you want a page only to be available for logged in users. You won’t need to authenticate again your user, just call the auth object like this:

<?php
//Some code of your own
//Get auth object
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()){
echo('You\'re in!');
}
else{
echo('Ooops! sorry, you need to login first');
}
?>

So there you go, quite simple isn’t it.

Hope this helps you start playing with ZF. I’ll post more stuff in the go.

PHPMailer & Hotmail showing an empty or blank screen

Tuesday, July 27th, 2010

Yes, as it reads.

I’ve been using PHPMailer class for a while but only a few days from now I received a complaint from a customer that told me he got an empty email with his order confirmation.

At first I assumed he was the only one experiencing this so I told him to tweek his Hotmail account or move to Gmail, Yahoo or a better service provider. Next thing I knew a couple more customers sent me an email with the same complain.

So, it’s only happening with Hotmail… Time to do some tests.

To my surprise email was arriving to destination address but it was showing nothing, it was a blank/empty email body. No way! somethings gotta be wrong! I right clicked the message and selected the view source option.

Ok, message content was there so something else is happening. Email headers, boundaries… something is causing the email not to be shown.

After a couple of days of searching and testing I came to this simple solution.

Go to phpmailer.class.php

Then search for code lines that look like this:

$result = ”;

switch ($this->message_type) {

case ‘plain’ :

$result .= $this->HeaderLine ( ‘Content-Transfer-Encoding’, $this->Encoding );

$result .= sprintf ( “Content-Type: %s; charset=\”%s\””, $this->ContentType, $this->CharSet );

break;

case ‘attachments’ :

case ‘alt_attachments’ :

if ($this->InlineImageExists ()) {

$result .= sprintf ( “Content-Type: %s;%s\ttype=\”text/html\”;%s\tboundary=\”%s\”%s”, ‘multipart/related’, $this->LE, $this->LE, $this->boundary [1], $this->LE );

} else {

$result .= $this->HeaderLine ( ‘Content-Type’, ‘multipart/mixed;’ );

$result .= $this->TextLine ( “\tboundary=\”” . $this->boundary [1] . ‘”‘ );

}

break;

case ‘alt’ :

$result .= $this->HeaderLine ( ‘Content-Type’, ‘multipart/alternative;’ );

$result .= $this->TextLine ( “\tboundary=\”” . $this->boundary [1] . ‘”‘ );

break;

}

Do you see the line where it reads: multipart/alternative

Change that into multipart/mixed

That’s it! Hotmail will display your AltBody content!

It worked for us so if it doesn´t work for you, then better start messing with the headers 😀

PHP & Oracle

Wednesday, July 21st, 2010

Long time no see.

Changed job and been working on fixing an app.

In my new job PHP and Oracle are the standards so I’m back to Oracle and I already had my first issues.

I have a small database with a couple of related tables.

I wanted to do an insert and get the id of the recently added row, searched for it on Google and there it was, I’ll need to use RETURNING…INTO.

It’s pretty simple actually so I coded it, the primary key is an integer that runs a trigger with a sequence, kind of a MySQL autoincrement field.

So this is how the code ended looking:

$query = “SELECT id, field1, field2 FROM table WHERE field1 IS NOT NULL RETURNING id into :id”;

$con = new connection()

$stmt = oci_parse($con,$query);

if($stmt!==false){

$binded = oci_bind_by_name($stmt,’:id’,$id);

$executed = oci_execute($stmt);

if($executed!==false){

$row = oci_fetch_array($stmt,OCI_BOTH+OCI_RETURN_NULLS+OCI_RETURN_LOBS);

}

}

It worked fine for a couple of days, then id started working oddly. I analized the code and found out that id was returning a 3 digits id instead of 4 digits, so I’ll be getting 123 for ids 1230 – 1239 besides the previous original 123. That was messing my database integrity and making my code to fail.

Googled it and found nothing! What the hell was wrong with it?

Finally after a day I calmed down and started to remember the old times when I started to work with Oracle and suddenly I remembered!!!!

I was missing a parameter on an oci function. I added it and voila! It worked!

What was I missing? Simple, I was missing the maxLength parameter for the oci_bind_by_name function.

Finally it ended looking like this:

$binded = oci_bind_by_name($stmt,’:id’,$id,100);

Hope this helps others with the same issue.

Sanitizing and validating data

Thursday, March 25th, 2010

Still working on a project I found the typical login form.

This time the login credentials are the user’s email and a password. As always I found myself facing the task of validating an email. I had some php functions to do so but since they were almost a year old I decided to search for a more powerful already working solution.

To my surprise I found some very interesting info about email’s validation that I was unaware.

Some stuff that caught my eyes was that the email RFC actually allows the use of special characters on an email. The followin email is valid:

“jimmy”\@home@gmail.com

Noticed the quoted string? what about the escaped @?

In fact the following characters are valid on an email username: !#$%&’*+-/=?^_`{|}~@.[]

Wow! I bet that most of us didn’t knew that, and what’s worst most javascript or PHP validation functions won’t validate with the proper RFC rules. Deep trouble!

The good news are that PHP as of version 5 provides some functions that would help us deal with this problem.

Read the manual and search for filters, you’ll find a couple of very interesting and helpful functions to sanitize and validate data.

As for the email the following gets the job done:

$sanitized_email = filter_var($email,FILTER_SANITIZE_EMAIL);

$valid_email = filter_var($sanitized_email,FILTER_VALIDATE_EMAIL);

if($valid_email!==false){

echo “Valid email!”;

}

It’s indeed a very helpful and concise way of validating data. The only bad thing is that it only works on PHP 5 or later. Nevertheless you’ll find some very powerful scripts on the links previously provided.

Hope this helps you as much as it helped me.

When random ain’t that random

Wednesday, March 24th, 2010

Been working on a small project that demanded the use of captcha.

Since it’s very small I decided to create my own captcha class. Nothing very complicated but still enough to avoid most of the spam robots. Anyway In order to create a nice captcha mi code draws some lines whose x,y coordinates where randomly generated through PHP’s rand function.

Later that day as I was finishing a widget I came up with this cool site. It’s all about randomness so I started reading.

To my surprise I found out a specific page that talked about pseudo random numbers generators (PRNG) and true random numbers generators (TRNG). PHP’s rand function is a PRNG and it’s not as cool as I thought.

For what the page explains the rand function should be avoided for true random number generatiosn when on a Windows server. Apparently it behaves oddly and follows some sort of pattern. They recommend the use of mt_rand instead which generates a more random number and also is faster than rand!!!!

Obviously I moved to mt_rand.

Please read the article, you’ll be surprised!!!

SocialGo API

Thursday, February 18th, 2010

We’ll this post is for remembering one very important issue with the SocialGo API.

I was doing a webpage that send users to their SGo page. So I used the SGo API.

I downloaded it and realized that when you download the API the corresponding keys (developer and network) are already assigned to the corresponding properties so I was doing this:

$api = new SNM_api();

$id = 'test@example.com'; //. user email OR user ID
$result = $api->getUserCrossDomainAuthURL($id);
$redirect_user_url = $result->member->attributes()->auth_url;

I’ve been dealing with the fact that I kept getting false as a result… What’s wrong with the code?

So I went to the blogs, even the SocialGo blogs and some developers wrote me saying I needed to set the network and developer keys. I was reluctant because the object already had the pproperties set so I thought it was a silly answer, till minutes ago when I finally gave up trying other solutions. It worked! I haven’t takn a look to the SGo API but it looks that you need to set this properties in order for the API to work so the code ends up like this:

$api = new SNM_api();

$api->setApiServer('http://api.socialgo.com/');
$api->setNetworkKey('<NETWORK_KEY>');
$api->setDeveloperKey('<DEV_KEY>');

$id = 'test@example.com'; //. user email OR user ID
$result = $api->getUserCrossDomainAuthURL($id);
$redirect_user_url = $result->member->attributes()->auth_url;
I'll never forget about this again.

call to undefined function json_decode

Sunday, February 14th, 2010

This sucks!

Again my dev env works perfectly and the production environment keeps throwing weird messages.

I’m using php json_decode to (you guessed it) decode  a json string. The server throws this ugly message!

What should I do?! Ok I realized my dev env uses PHP 5.2…. the production server uses 5.1.6. What does that have to do? Well for some reason PHP 5.1.6 doesn’t have json support, in order to support the calls you should either upgrade php or pear install it.

I tried updating to php 5.2, and didn’t worked so I ended installing the pear support.

Remember to include the proper paths.

Lock wait timeout exceeded; try restarting transaction

Sunday, February 14th, 2010

So last friday I came up with this nasty message… Believe me, it was a very troublesome issue to solve. We have MySQL running Innodb for a couple of tables. We wanted to modify 3 tables and we decided to create a transaction if inserts and updates went ok then commit if not rollback.

I did it and tested it on my dev env (my lap hehehehe) and it all worked fine, speed was ok and everything worked as wanted. So I commited it to my svn server and uploaded the code to the production server. 5 min. before I leave the office my boss decided to test the new version…. good and bad idea, good because he got the nasty error, bad because of the time.

Anyway, we saw the error. Initially I thought it was because of a web service (no, I didn’t realized it was a database issue), then after discarding lots of probable errors I realize it was a transaction error. After hours looking and reading google search results I learned the following: When doing a transaction tables involved receive a lock, the lock is released once the transaction ends. If a table is being updated within the transaction and you try to select data from it then you’ll be trying to access a locked table, since it is locked you can’t read from it and since you can’t read from it you can’t finish the transaction so the waiting for the lock to release takes for ever and the connection throws the error:

“Lock wait timeout exceeded; try restarting the transaction”

How did I solved it?

After trying docens of solutions without success I finally realized that I had to take the reading statements off the transaction.

It worked! And because I forget things very fast I decided to put it here.

Hope it helps someone else out there.

PHP Curl

Wednesday, December 9th, 2009

Wow! I’m amazed by the power of this library!

It’s been a while since the last time I posted anything. I’m in another company and with new challenges.

The main project/reason this other company hired me was to connect 2 different closed web applications they bought. One of them will be used to manage users access and privileges and the other will manage the content. The first one is hosted in our server and it’s encrypted with zend guard, the other is a hired service and they don’t provide any access to code, database or anything that has to do with providing access to their servers but they provide an API.

The encrypted software gives you the availability to modify 2 files and thats all.

So the project was doing well, the API seemed to be the solution but then I got to a piece of data that the API doesn’t handle and is the very core of this integration. I thought I was missing something so I started Googling it, went into phorums, asked for support, submited tickets and nobody would give me a proper answer… damn! so I decided I’ll do it by myself.

A year ago I heard about CURL, I even bought a book and started studying it but it was useless at the time, no project needed anything from it so everything was forgotten until now.

Since the data I needed to modify from the API was available through a web admin console I decided to use CURL, access the admin console, get to the page where the data could be modified and modify it… took me a couple of hours… It’s done!

I’m very excited, and just wanted to write this down.