Friday, July 19, 2013

Create a Zip File Using PHP

 

Creating .ZIP archives using PHP can be just as simple as creating them on your desktop. PHP's ZIP class provides all the functionality you need! To make the process a bit faster for you, I've coded a simple create_zip function for you to use on your projects.

The PHP

/* creates a compressed zip file */
function create_zip($files = array(),$destination = '',$overwrite = false) {
 //if the zip file already exists and overwrite is false, return false
 if(file_exists($destination) && !$overwrite) { return false; }
 //vars
 $valid_files = array();
 //if files were passed in...
 if(is_array($files)) {
  //cycle through each file
  foreach($files as $file) {
   //make sure the file exists
   if(file_exists($file)) {
    $valid_files[] = $file;
   }
  }
 }
 //if we have good files...
 if(count($valid_files)) {
  //create the archive
  $zip = new ZipArchive();
  if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
   return false;
  }
  //add the files
  foreach($valid_files as $file) {
   $zip->addFile($file,$file);
  }
  //debug
  //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
  
  //close the zip -- done!
  $zip->close();
  
  //check to make sure the file exists
  return file_exists($destination);
 }
 else
 {
  return false;
 }
}

Sample Usage

$files_to_zip = array(
 'preload-images/1.jpg',
 'preload-images/2.jpg',
 'preload-images/5.jpg',
 'kwicks/ringo.gif',
 'rod.jpg',
 'reddit.gif'
);
//if true, good; if false, zip creation failed
$result = create_zip($files_to_zip,'my-archive.zip');
The function accepts an array of files, the name of the destination files, and whether or not you'd like the destination file to be overwritten if a file of the same name exists. The function returns true if the file was created, false if the process runs into any problems.

Thursday, January 17, 2013

Microsoft HTTPAPI/2.0 disabling Apache

 

I’be been working on php for 2 months now and developing on my laptop with WAMP installed before uploading to work’s dev server. Now working with SQL Server instead of MySQL, I’ve installed SQL SERVER 2008 CTP for test and suddently Apache went down as port 80 was used by Microsoft HTTPAPI/2.0.
I then found SSRS (SQL Server Reporting Services) was still running after uninstalling SQL Server 2008 as it features a web service even though IIS is not installed according to wiki.
I couldn’t find any info on google relating to this small issue that puzzled me for a short while. i hope this helps finding ppl stupid like me sometimes to solve their problem

 


Monday, January 14, 2013

entered value from child window to parent window

From a child window or a small window once opened, we can transfer any user entered value to main or parent window by using JavaScript. You can see the demo of this here. Here the parent window is known as opener. So the value we enter in a child window we can pass to main by using opener.document object model. So if the name of the form in parent window is f1 and the text box where we want the value to be passed is p_name ( in parent window ) then from the child window we can access them by using the object.

opener.document.f1.p_name

The value for this object can be assigned like this

opener.document.f1.p_name.value="Any value";

We will try to make it interactive so we will assign this to a value entered by the user. Then we will use one input box in child window and name it as c_name. So we can pass the value of the input box of child window to the parent window input box by this line.

opener.document.f1.p_name.value = document.frm.c_name.value;

Related Tutorial
Refreshing the parent window
Opening Window
We will keep this line inside a function and call this function on click of a button. Inside the function after executing the above line we will add the code to close the child window. Like this ..

opener.document.f1.p_name.value = document.frm.c_name.value;
self.close();

To open the child window this is the code used in parent window



Your Name
onClick=window.open("child3.html","Ratting",
"width=550,height=170,left=150,top=200,toolbar=1,status=1,");>Click here to open the child window


Inside the Child window code is here






(Type a title for your page here)










Your name

In the above code take care that there is no line break ( in parent file ) in line saying onClick=window.open(......

How to create GD Image from base64 encoded jpeg?

How to create GD Image from base64 encoded jpeg?

 

$data = base64_decode($_POST['image_as_base64']);

$formImage = imagecreatefromstring($data);
"String" does not mean a "real" string. In that case it means bytes/blob data.

 

Monday, November 5, 2012

How to upload image(photo), and path entry in database with update functionality


I saw many posts that community newbie is confuse in image/photo upload with random name. so I post this topic covering all useful things regarding to image/photo upload(not covering image attribute related functionality)

View :

_form.php file:
..
//form options array...
'htmlOptions' => array(
        'enctype' => 'multipart/form-data',
    ),
...
..
//Other elements
..
..
<div class="row">
        php echo $form->labelEx($model,'image'); ?>
        php echo CHtml::activeFileField($model, 'image'); ?>  // by this we can upload image
        php echo $form->error($model,'image'); ?>
</div>
php if($model->isNewRecord!='1'){ ?>
echo CHtml::image(Yii::app()->request->baseUrl.'/banner/'.$model->image,"image",array("width"=>200)); ?> // Image shown here if page is update page
.. .. Other elements .. ..
.. ..

Model :

just add below line in rules() method in Model
array('image', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'), // this will allow empty field when page is update (remember here i create scenario update)
for all others rules you had to give scenario for insert and update as the rule will apply on both page( Insert and Update ) i.e:
array('title, image', 'length', 'max'=>255, 'on'=>'insert,update'),
.. .. Now comes the main part,

Controller :

Create controller will upload image with random name and enter required database entry.
public function actionCreate()
    {
        $model=new Banner;  // this is my model related to table
        if(isset($_POST['Banner']))
        {
            $rnd = rand(0,9999);  // generate random number between 0-9999
            $model->attributes=$_POST['Banner'];
 
            $uploadedFile=CUploadedFile::getInstance($model,'image');
            $fileName = "{$rnd}-{$uploadedFile}";  // random number + file name
            $model->image = $fileName;
 
            if($model->save())
            {
                $uploadedFile->saveAs(Yii::app()->basePath.'/../banner/'.$fileName);  // image will uplode to rootDirectory/banner/
                $this->redirect(array('admin'));
            }
        }
        $this->render('create',array(
            'model'=>$model,
        ));
    }
Now comes the update action,
public function actionUpdate($id)
    {
        $model=$this->loadModel($id);
 
        if(isset($_POST['Banner']))
        {
            $_POST['Banner']['image'] = $model->image;
            $model->attributes=$_POST['Banner'];
 
            $uploadedFile=CUploadedFile::getInstance($model,'image');
 
            if($model->save())
            {
                if(!empty($uploadedFile))  // check if uploaded file is set or not
                {
                    $uploadedFile->saveAs(Yii::app()->basePath.'/../banner/'.$model->image);
                }
                $this->redirect(array('admin'));
            }
 
            if($model->save())
                $this->redirect(array('admin'));
        }
 
        $this->render('update',array(
            'model'=>$model,
        ));
    }

Monday, October 29, 2012


I'm trying to add a reference from the default Spring Security user domain class to another class which should hold additional user info.
class User {
    transient springSecurityService

    String username
    String password
    boolean enabled
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    Profile profile
      ...
...and...
class Profile {
    static constraints = {
    }

    static belongsTo = [user : User]

    String firstName
    String lastName     
}
From what I read this should be the way it works, but I get the following error :
ERROR context.GrailsContextLoader  - Error executing bootstraps: null
Message: null
   Line | Method
->>  32 | create                           in com.app.UserRole
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    15 | doCall                           in BootStrap$_closure1
|   301 | evaluateEnvironmentSpecificBlock in grails.util.Environment
|   294 | executeForEnvironment            in     ''
|   270 | executeForCurrentEnvironment . . in     ''
|   303 | innerRun                         in java.util.concurrent.FutureTask$Sync
|   138 | run . . . . . . . . . . . . . .  in java.util.concurrent.FutureTask
|   886 | runTask                          in java.util.concurrent.ThreadPoolExecutor$Worker
|   908 | run . . . . . . . . . . . . . .  in     ''
^   662 | run                              in java.lang.Thread
Any idea?

=======================================================================

We need to see your BootStrap to be sure, but I suspect it's because you're doing something like
def user = new User(....).save()
def role = new Role(....).save()
UserRole.create(user, role)
and your new User is failing validation (which causes save to return null).
If you use save(failOnError:true) you should get a different exception with a better indication of what the real problem is. Check that you have the right constraints in your User class, in particular note that GORM properties are by default non-nullable so if you want to be able to save a User that doesn't have a Profile you will need to add a constraint of profile(nullable:true).

Monday, October 22, 2012

PHP Database Access: Are You Doing It Correctly?

Tutorial Details

  • Topic - Database Access in PHP
  • Difficulty - Moderate
We've covered PHP's PDO API a couple of times here on Nettuts+, but, generally, those articles focused more on the theory, and less on the application. This article will fix that!
To put it plainly, if you're still using PHP's old mysql API to connect to your databases, read on!


What?

It's possible that, at this point, the only thought in your mind is, "What the heck is PDO?" Well, it's one of PHP's three available APIs for connecting to a MySQL database. "Three," you say? Yes; many folks don't know it, but there are three different APIs for connecting:
  • mysql
  • mysqli – MySQL Improved
  • pdo – PHP Data Objects
The traditional mysql API certainly gets the job done, and has become so popular largely due to the fact that it makes the process of retrieving some records from a database as easy as possible. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * Anti-Pattern
 */
# Connect
mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());
# Choose a database
mysql_select_db('someDatabase') or die('Could not select database');
# Perform database query
$query = "SELECT * from someTable";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
# Filter through rows and echo desired information
while ($row = mysql_fetch_object($result)) {
    echo $row->name;
}
Yes, the code above is fairly simple, but it does come with its significant share of downsides.
  • Deprecated: Though it hasn't been officially deprecated – due to widespread use – in terms of best practice and education, it might as well be.
  • Escaping: The process of escaping user input is left to the developer – many of which don't understand or know how to sanitize the data.
  • Flexibility: The API isn't flexible; the code above is tailor-made for working with a MySQL database. What if you switch?
PDO, or PHP Data Objects, provides a more powerful API that doesn't care about the driver you use; it's database agnostic. Further, it offers the ability to use prepared statements, virtually eliminating any worry of SQL injection.

How?

When I was first learning about the PDO API, I must admit that it was slightly intimidating. This wasn't because the API was overly complicated (it's not) – it's just that the old myqsl API was so dang easy to use!
Don't worry, though; follow these simple steps, and you'll be up and running in no time.

Connect

So you already know the legacy way of connecting to a MySQL database:
1
2
# Connect
mysql_connect('localhost', 'username', 'password') or die('Could not connect: ' . mysql_error());
With PDO, we create a new instance of the class, and specify the driver, database name, username, and password – like so:
1
$conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
Don't let that long string confuse you; it's really very simple: we specify the name of the driver (mysql, in this case), followed by the required details (connection string) for connecting to it.
What's nice about this approach is that, if we instead wish to use a sqlite database, we simply update the DSN, or "Data Source Name," accordingly; we're not dependent upon MySQL in the way that we are when use functions, like mysql_connect.

Errors

But, what if there's an error, and we can't connect to the database? Well, let's wrap everything within a try/catch block:
1
2
3
4
5
6
try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
That's better! Please note that, by default, the default error mode for PDO is PDO::ERRMODE_SILENT. With this setting left unchanged, you'll need to manually fetch errors, after performing a query.
1
2
echo $conn->errorCode();
echo $conn->errorInfo();
Instead, a better choice, during development, is to update this setting to PDO::ERRMODE_EXCEPTION, which will fire exceptions as they occur. This way, any uncaught exceptions will halt the script.
For reference, the available options are:
  • PDO::ERRMODE_SILENT
  • PDO::ERRMODE_WARNING
  • PDO::ERRMODE_EXCEPTION

Fetch

At this point, we've created a connection to the database; let's fetch some information from it. There's two core ways to accomplish this task: query and execute. We'll review both.

Query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * The Query Method
 * Anti-Pattern
 */
$name = 'Joe'; # user-supplied data
try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $data = $conn->query('SELECT * FROM myTable WHERE name = ' . $conn->quote($name));
    foreach($data as $row) {
        print_r($row);
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
Though this works, notice that we're still manually escaping the user's data with the PDO::quote method. Think of this method as, more or less, the PDO equivalent to use mysql_real_escape_string; it will both escape and quote the string that you pass to it. In situations, when you're binding user-supplied data to a SQL query, it's strongly advised that you instead use prepared statements. That said, if your SQL queries are not dependent upon form data, the query method is a helpful choice, and makes the process of looping through the results as easy as a foreach statement.

Prepared Statements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * The Prepared Statements Method
 * Best Practice
 */
$id = 5;
try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
    $stmt->execute(array('id' => $id));
    while($row = $stmt->fetch()) {
        print_r($row);
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
In this example, we're using the prepare method to, literally, prepare the query, before the user's data has been attached. With this technique, SQL injection is virtually impossible, because the data doesn't ever get inserted into the SQL query, itself. Notice that, instead, we use named parameters (:id) to specify placeholders.
Alternatively, you could use ? parameters, however, it makes for a less-readable experience. Stick with named parameters.
Next, we execute the query, while passing an array, which contains the data that should be bound to those placeholders.
1
$stmt->execute(array('id' => $id));
An alternate, but perfectly acceptable, approach would be to use the bindParam method, like so:
1
2
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();

Specifying the Ouput

After calling the execute method, there are a variety of different ways to receive the data: an array (the default), an object, etc. In the example above, the default response is used: PDO::FETCH_ASSOC; this can easily be overridden, though, if necessary:
1
2
3
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
    print_r($row);
}
Now, we've specified that we want to interact with the result set in a more object-oriented fashion. Available choices include, but not limited to:
  • PDO::FETCH_ASSOC: Returns an array.
  • PDO::FETCH_BOTH: Returns an array, indexed by both column-name, and 0-indexed.
  • PDO::FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound.
  • PDO::FETCH_CLASS: Returns a new instance of the specified class.
  • PDO::FETCH_OBJ: Returns an anonymous object, with property names that correspond to the columns.
One problem with the code above is that we aren't providing any feedback, if no results are returned. Let's fix that:
1
2
3
4
5
6
7
8
9
10
11
$stmt->execute(array('id' => $id));
# Get array containing all of the result rows
$result = $stmt->fetchAll();
# If one or more rows were returned...
if ( count($result) ) {
    foreach($result as $row) {
        print_r($row);
    }
} else {
    echo "No rows returned.";
}
At this point, our full code should look like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$id = 5;
try {
  $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
  $stmt->execute(array('id' => $id));
  $result = $stmt->fetchAll();
  if ( count($result) ) {
    foreach($result as $row) {
      print_r($row);
    }
  } else {
    echo "No rows returned.";
  }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

Multiple Executions

The PDO extension becomes particularly powerful when executing the same SQL query multiple times, but with different parameters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try {
  $conn = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  # Prepare the query ONCE
  $stmt = $conn->prepare('INSERT INTO someTable VALUES(:name)');
  $stmt->bindParam(':name', $name);
  # First insertion
  $name = 'Keith';
  $stmt->execute();
  # Second insertion
  $name = 'Steven';
  $stmt->execute();
} catch(PDOException $e) {
  echo $e->getMessage();
}
Once the query has been prepared, it can be executed multiple times, with different parameters. The code above will insert two rows into the database: one with a name of “Kevin,” and the other, “Steven.”

CRUD

Now that you have the basic process in place, let’s quickly review the various CRUD tasks. As you’ll find, the required code for each is virtually identical.

Create (Insert)

1
2
3
4
5
6
7
8
9
10
11
try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $stmt = $pdo->prepare('INSERT INTO someTable VALUES(:name)');
  $stmt->execute(array(
    ':name' => 'Justin Bieber'
  ));
  # Affected Rows?
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();

Update

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$id = 5;
$name = "Joe the Plumber";
try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $stmt = $pdo->prepare('UPDATE someTable SET name = :name WHERE id = :id');
  $stmt->execute(array(
    ':id'   => $id,
    ':name' => $name
  ));
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Delete

1
2
3
4
5
6
7
8
9
10
11
$id = 5; // From a form or something similar
try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $stmt = $pdo->prepare('DELETE FROM someTable WHERE id = :id');
  $stmt->bindParam(':id', $id); // this time, we'll use the bindParam method
  $stmt->execute();
  echo $stmt->rowCount(); // 1
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Object Mapping

One of the neatest aspects of PDO (mysqli, as well) is that it gives us the ability to map the query results to a class instance, or object. Here’s an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class User {
  public $first_name;
  public $last_name;
  public function full_name()
  {
    return $this->first_name . ' ' . $this->last_name;
  }
}
try {
  $pdo = new PDO('mysql:host=localhost;dbname=someDatabase', $username, $password);
  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $result = $pdo->query('SELECT * FROM someTable');
  # Map results to object
  $result->setFetchMode(PDO::FETCH_CLASS, 'User');
  while($user = $result->fetch()) {
    # Call our custom full_name method
    echo $user->full_name();
  }
} catch(PDOException $e) {
  echo 'Error: ' . $e->getMessage();
}

Closing Thoughts

Bottom line: if you’re still using that old mysql API for connecting to your databases, stop. Though it hasn’t yet been deprecated, in terms of education and documentation, it might as well be. Your code will be significantly more secure and streamlined if you adopt the PDO extension.