Friday, August 31, 2018

Changing the Filename of a File Downloaded over a PHP Script

You may be downloading files on your server with PHP by a combination of the header() and readfile() functions, like so...

header("Content-disposition: attachment;filename=MyFileName.txt");
readfile("../data/MyFileName.txt");

The filename on the server, and the one the user sees, will both have the same name. But you can change the filename the user sees, with something like this...

header("Content-disposition: attachment;filename=MyUSERONLYFileName.txt");
readfile("../data/MyFileName.txt");

Your server knows to look for the file in ../data/MyFileName.txt, and now, your user will receive a file with teh name of MyUSERONLYFilename.txt, instead of MyFileName.txt.

Thursday, August 30, 2018

How do I Download a File to the User with my PHP script?

If you have a text file on your PHP server, you may have tried to download it through your PHP script with just this...

readfile("../data/MyTextFileName.txt");

But, as you would have noticed, it doesn't download the file. It displays the file contents in the browser.

To download the file, you must also include headers, used by HTTP to determine how to treat the web server's response, like this...

header("Content-disposition: attachment;filename=MyFileName.txt");
readfile("../data/MyTextFileName.txt");

After running the above, the user will be prompted with a question about whether they want to open or save a downloaded file, or however their particular browser is configured to handle downloads.

Wednesday, August 29, 2018

Creating a GZip Archive on Your PHP Server to Serve to Web Users

Gzip is a popular zip-archive format for storing files in the long-term. Users benefit from this by reducing the download time, or by being able to group files together in a single download link.

You may have files on your PHP server, of any type (image, documents, code, etc.), and you may want to zip these files in a GZip archive automatically with your PHP script.

You can create a gzip file with something like this...

$filep = gzopen("../data/MyZipFileName.gz", 'w9');

Then you write whatever text you want to it with something like this...

gzwrite($filep, $text);

When you are finished, you let the PHP server know you're done by adding this to the end of your script...

gzclose($filep);

If you want to download this as a file, you need to send file headers, so that you download the gzip file at the PHP URL, instead of just looking at the gzip file contents through the browser (which would be a garbled mess, as it is a compressed archive).

You can do that with this...

header("Content-disposition: attachment;filename=MyArchiveFile.gz");
readfile("../data/MyZipFileName.gz");

Tuesday, August 28, 2018

Downloading and Unzipping GZip on Your PHP Server From Another Web Server

Some site may offer a gzip file that you want to run with your PHP script, but that gzip file is always being updated and you want your script to download the newest version and use its contents.

This can be done very easily.

First, download the file you want to unzip, using something like this...

$file = file_put_contents("../data/SomeZipFileLocation.gz", fopen("SomeURL", 'r'), LOCK_EX);

Then you can read the contents like this...

$file = gzopen("../data/SomeZipFileLocation.gz", 'rb');
while (!gzeof($file)) {
print(gzread($file, 4000));
}

This will loop through each of the 4,000 bytes in the file from the gzip and display them.

Using this technique, you won't ever have to manually download and unzip these gzipped files to use the newest version with your code.

Monday, August 27, 2018

Using HTAccess to Redirect All Users (and POST data) to the Same URL

With the Apache .htaccess file, you can control a good number of things on your server.

If you turn on the RewriteEngine, you can have one URL example.com/123, always return the results of another URL, like example.com/index.php?id=123.

To do this, you need to have a .htaccess file in the base directory of your apache htdocs folder. It should start with this...

RewriteEngine On
RewriteBase /

And, it can redirect everyone to index.php with this...

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,NC,L]

You can change index.php to anything you like, of course. Then you can get the information about the original URL by using the $_POST parameters, which you can see with...

print_r($_POST);

Sunday, August 26, 2018

How do I Salt and Encrypt Passwords in PHP?

Salting a password occurs when you add text to a password to make it longer and more complex.

For instance, "myPassWord" would be "myPassWordSomeSalt". Since this is longer, when it is encrypted, it will become a more complex result.

Then when you compare the "salted password" to a user's password, you just append "SomeSalt" to the user's input. Your condition looks like...

if(COMPARE($_POST['password'] . 'SomeSalt', $db['password'])) {...}

While this was useful at one time, this concept of salting is now built-in to passwords in PHP. You can simply do...

$hash = password_hash($password, PASSWORD_DEFAULT);
if(password_verify($password, $hash) {
// password is valid!
}

This saves you time in coding, and also means that a more reliable, mathematically-based password salt is generated and used.

Source: http://php.net/manual/en/function.password-hash.php

Saturday, August 25, 2018

What values are valid for an ID attribute in an HTML element?

When naming id attributes of HTML tags, you do have some limits.

As stated by the HTML4 specification...

>> ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

Source: https://www.w3.org/TR/html4/types.html#type-id

HTML5 has more-relaxed specifications...

There are no other restrictions on what form an ID can take; in particular, IDs can consist of just digits, start with a digit, start with an underscore, consist of just punctuation, etc.

Source: https://www.w3.org/TR/html5/dom.html#element-attrdef-global-id

Friday, August 24, 2018

How to Detect the Character Set Encoding of a MySQL Database

You may want to know if your MySQL DB is encoded in latin1 or UTF-8, or maybe some other charset.

You can see the default character set encoding and collation with these commands...

SELECT @@character_set_database;
SELECT @@collation_database;

But this is just for the current database. There are various other default encodings and collations at different levels, which you will only be able to see with commands like these...

show variables like 'char%';
show variables like 'collation%';

If you want to see the encoding for a particular table, you can find its encoding with...

SHOW CREATE TABLE MyTable;

To see ONLY the encoding of a particular Table's field, you can search the INFORMATION_SCHEMA tables...

SELECT COLLATION_NAME
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'MySchema'
AND TABLE_NAME = 'MyTable'
AND COLUMN_NAME = 'MyField';

Thursday, August 23, 2018

Full UTF-8 Web Application Development - How to Do It Right

With UTF-8 support, you can be guaranteed that any language will work with your code. But there are two fundamental things that you need to make sure happens:

First, convert your database to UTF-8. This is the data part of it.

To convert your database requires changing the default settings and converting the tables themselves. You can change the default settings with...

MyDB@sys mysql> ALTER DATABASE MyDatabase DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

And you can convert your tables with...

MyDB@sys mysql> ALTER TABLE MyTable DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
MyDB@sys mysql> ALTER TABLE MyTable MODIFY MyColumn VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';

Second, send all web pages with a UTF-8 header. This is the networking part of it.

For example, in PHP, to send the UTF-8 header, you will run this command being sending any output to the browser...

header('Content-type: text/html; charset=utf-8');

Every program, protocol, etc., has its exceptions and variations, so these are just the two basics you need to handle.

Wednesday, August 22, 2018

"bind_param() expects parameter 1 to be resource, boolean given" -- Possible Fixes?

Your MySQL and PHP code may be fully and logically thought-out. You may have even tested and verified it worked. But now you have this error:

"bind_param() expects parameter 1 to be resource, boolean given"

Your code probably looks something like this...

$db_link = new mysqli($hostname, $username, $password, $database);
$sql = "SELECT * FROM SomeTable WHERE id = ?";
$statement = $db_link->prepare($sql);
$statement->bind_param($_POST['id']);

How do you fix it? The problem is not with the bind_param() function, it's with the prepare() or the mysqli() functions!

If statement is a boolean, that means it is true or false, and in this case, false means that either mysqli() could not connect to the DB, or that prepare() had a problem.

If mysqli() has a problem, it could be a bad username/password combination, a networking issue, a bad db name, or something else. If prepare() has a problem, it could be a bad query, an unescaped term in the query, or something like that.

You can verify that mysqli() worked, by displaying its result and seeing that it's not false, and similarly with prepare().