Tuesday 28 August 2012

Saving and retrieving images using MySQL through PHP

I really should have looked into this a long time ago, but still. The example below deliberately doesn't use jQuery. If you want to POST files through jQuery, you'll need to use an ajax form plugin.

Right. Now we've got that out of the way, to my example. I have created a database in MySQL with a table called pictures, and I have 2 fields:
id : int(8)

picture : longblob
I have used the database class which I developed earlier to handle the requests.
At this stage, I'm just handling JPEG images.


<?php
require_once 'database.class.php';
$db = new database;
if($_POST)
{
$image=$_FILES['uploadfile']['tmp_name'];
$fp = fopen($image, 'r');
$content = fread($fp, filesize($image));
$content = addslashes($content);
fclose($fp);
$sql="insert into pictures (picture) values ('$content')";
$results = $db->query($sql);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File upload</title>
</head>
<body>
<form enctype="multipart/form-data" method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="MAX_FILE_SIZE" value="10000000" />
<input name="uploadfile" id="uploadfile" type="file" />
<input type="submit" value="Submit" />
</form>
<div id="results">
<?php
$arr = $db->query('SELECT * FROM pictures');
if($arr)
{
foreach($arr as $row)
{
echo $row['id'];
echo '<img src="data:image/jpeg;base64,'.base64_encode($row['picture']).'" /><br />';
}
}
?>
</div>
</body>
</html>

Enjoy!

Monday 20 August 2012

Useful PHP quick test page

I developed this page a little while ago to do quick tests. Essentially, you just put items in the text box and press submit. The benefit of the page is that all the reloading is done for you. There is no need to keep using back or forward buttons. Just carry on making adjustments to your code and keep trying. The page will use the changes you make.

In the example below, I am outputing an md5 version of my input, but you can create your own functions and just replace the bit where md5 is called (highlighted in red).


<?php
$myname = $_GET ? html_entity_decode($_GET['myname']) : NULL;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!--[if IE]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" />
<style>
</style>
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1");
</script>
</head>
<body>
<form>
<label for="myname">Type your string</label>
<input type="text" name="myname" id="myname" value="<?php  echo $myname; ?>" />
<button type="submit">Submit</button>
</form>
<p><?php echo $myname ? md5($myname) : NULL; ?></p>
<script>
(function()
{
  $('form').submit(function()
  {
    locStr = '<?php echo basename(__FILE__); ?>?str='+$('#myname').val();
    window.location.replace(locStr);
  }
})();
</script>
</body>
</html>

Thursday 9 August 2012

Lessons learned from the coal face of git repositories


I've just been going through a bit of pain, setting up a git repo.

A git repo is a place to put your open source project. It allows users to get hold of your project, contribute to it and create their own version from it. A git repo also gives you useful things like change control for your project.

GitHub have tried to make the process simple with good help, but there are a few do's and don'ts which I discovered along the way so here, I compose my learning as a reminder to myself. Hopefully we'll all feel the benefit.

I'm going to assume that you have already gone through all the pain of creating a GitHub account. There are many places on the web you can learn how to do this. I'm also assuming that you have logged in to GitHub and that you have reached the homepage of your account. Finally, I'll have to assume you've set git up on your server so that all the local software is in place.

1. It's best to create a new repository from GitHub. Not, as they recommend from your server. Start by clicking the 'New repository' buutton.
2. I recommend you name the repository as the directory on your server. Do not take the option to create the README file. By avoiding it, you will be provided with some starting commands, which I recommend you save to a text file. They'll look something like this:
Create a new repository on the command line
touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/yourusername/yourdirectory.git
git push -u origin master

Push an existing repository from the command line
git remote add origin https://github.com/yourusername/yourdirectory.git
git push -u origin master

3. Follow the instructions provided by GitHub within the directory on your server.
4. You may already have a project ready to go up. Then you'll need to do:
git add *.*
git commit -m "your comments"
git push origin master
Followed by:
git add .
git commit -m "your comments"
git push origin master
5. Now you're ready to start pushing your updates. Make some changes. Test that you're happy with them on your server. Now commit using:
git add *.*
git commit -m "your comments"
git push origin master
6. Let's say you messed up (each and every minute of every day in my case (yes, even when I'm sleeping)) and you want to remove a file you've committed. First delete it from your server then:
git add . -A
git commit -m "removed some files"
git push origin master

Have fun with GitHub!

Tuesday 7 August 2012

Hiding website directories from Johnnie Hacker using a .htaccess file

OK, here's the situation.
You're creating a website.
You want a directory called say 'classes'.
You need to access stuff contained in 'classes', but you don't want a user of your site to access the 'classes' directory through something like this http://www.yoursite.com/classes/
I'm assuming you've shown the good sense to use the apache web server here and that you haven't fallen foul of the Microsoft marketing machine or foolishly believed that you get what you pay for. That said, there are some good web servers other than apache.
I digress. Anyway, here is how to do it.


Go into the directory you wish to deny access to.
Create a file called .htaccess
Add a single line to the file namely:
deny from all
Save the file and restart apache.


If for some reason this doesn't work, it may be the way your apache server is set up.
Look for a file such as:
/etc/apache2/sites-available/default
That's if you're using a proper operating system. Goodness knows what it would be if you were using Windows.
In here you will see a few lines which look like this:

<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
Change the line which says 'AllowOverride None' to 'AllowOverride All'.
Now restart apache again.

You can now add similar .htaccess files to any directories you want to control.

OOP PHP Authentication Class

This class relies upon the existence of a databases class, such as the one listed here, to go away and check of the username and password match. If they do, a session and cookie is created.


<?php
require_once 'database.class.php';

class authenticate
{
public $id;
private $username;
private $password;
private $db;

function __construct()
{
$this->db = new database;
}

function login($u, $p)
{
$this->username = mysql_real_escape_string($u);
$this->password = mysql_real_escape_string(md5($p));
$q = "SELECT * FROM users WHERE username='{$this->username}' AND password='{$this->password}'";
$result = $this->db->query($q);
if($result)
{

    $this->id = $result->id;
    $this->username = $result->username;

$this->createSessionAndCookies();
}
else
{
$this->destroySessionAndCookies();
}
}

function logout()
{
$this->destroySessionAndCookies();
}

private function createSessionAndCookies()
{
@session_start();
$_SESSION['AUTH_ID'] = $this->id;
$_SESSION['AUTH_USERNAME'] = $this->username;
$expire=time()+3600*24*30;
setcookie('AUTH_ID', $this->id, $expire);
setcookie('AUTH_USERNAME', $this->username, $expire);
echo 'session and cookie created';
}

private function destroySessionAndCookies()
{
unset($_SESSION['AUTH_ID']);
unset($_SESSION['AUTH_USERNAME']);
session_destroy();
setcookie('AUTH_ID', '', time()-3600);
setcookie('AUTH_USERNAME', '', time()-3600);
echo 'session and cookie destroyed';
}

function __destruct()
{

}
}
?>

Monday 6 August 2012

OOP PHP Vimeo Class

This is essentially the earlier mentioned RSS class with a couple of tweaks for vimeo and search.

First, a script to call the class:

<?php
require_once 'vimeo.class.php';

$addr1 = 'http://vimeo.com/api/v2/channel/videoschool/videos.xml';
$addr2 = 'http://vimeo.com/api/v2/channel/wineaftercoffee/videos.xml';

$vimeo = new vimeo;
$vimeo->addFeed($addr1);
$vimeo->addFeed($addr2);

$arr = $vimeo->getFeed();

/* Or
$arr = $vimeo->getFeed('water');
*/

/*
Or
$searchArray = Array('glass', 'trix');
$arr = $vimeo->getFeed($searchArray);
*/

foreach($arr as $row)
{
echo '<iframe src="http://player.vimeo.com/video/'.$row->id.'" width="WIDTH" height="HEIGHT" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe><br />';
}
?>


Now, the class itself:


<?php
class vimeo
{
public $addr = NULL;
private $outArr = Array();
function __construct($addr = NULL)
{
$this->addr = $addr != NULL ? $addr : $this->addr;
if($this->addr)
{
return $this->addFeed();
}
}

function addFeed($addr = NULL)
{
$this->addr = $addr != NULL ? $addr : $this->addr;
$rss = simplexml_load_file($this->addr);
$this->outArr = array_merge($this->outArr, $rss->xpath('/videos//video'));
}

function getFeed($input = NULL)
{
usort($this->outArr, function ($x, $y)
{
if (strtotime($x->pubDate) == strtotime($y->pubDate)) return 0;
    return (strtotime($x->pubDate) > strtotime($y->pubDate)) ? -1 : 1;
});

if(is_array($input))
{
$this->outArr = $this->getArrayFilteredFeed($input);
}
elseif(is_string($input))
{
$this->outArr = $this->getStringFilteredFeed($input);
}

return $this->outArr;
}

private function getStringFilteredFeed($s)
{
$tempArr = Array();
foreach($this->outArr as $row)
{
if(stristr($row->title,$s) || stristr($row->description,$s))
{
array_push($tempArr, $row);
}
}
return $tempArr;
}

private function getArrayFilteredFeed($arr)
{
$tempArr = Array();
foreach($this->outArr as $row)
{
foreach ($arr as $key) 
{
if(stristr($row->title,$key) || stristr($row->description,$key))
{
array_push($tempArr, $row);
}
}
}
return $tempArr;
}
}
?>