Force multiple file download with PHP - php

I am trying to write a little script to backup all my localhost databases at once in seperate files. Currently my script does the backup part but does the download in one file. (So i get something like 30MB information_schema_backup.sql ) What i want is db_name_backup.sql for each database. Here is my code.
<?
function backup_dbs()
{
global $db_name;
global $dosyaadi; //dosyaadi means filename.
$return='';
/*
Backup Part Here;
I can share if anyone needs.
I will post this on my blog anyway.
*/
//save file
$dosyaadi=$db_name.'-backup-'.time().'.sql';
header("Content-type: application/octet-stream");
header("Content-disposition: attachment;filename=$dosyaadi");
echo $return;
}
$db_host = 'localhost';
$db_user = 'root';
$db_pass = '';
$db = mysql_connect($db_host, $db_user, $db_pass);
mysql_query("SET NAMES 'utf8'", $db);
mysql_query("SET CHARACTER SET utf8", $db);
mysql_query("SET COLLATION_CONNECTION = 'utf8_general_ci'", $db);
$res = mysql_query("SHOW DATABASES");
while ($row = mysql_fetch_assoc($res)) {
$db_name = $row['Database'];
mysql_select_db($db_name, $db);
backup_dbs();
}
die();
?>
Thanks in advance.

Related

How do i reorganize my php code to include separate db info file

Can any of you guys help me to reorganize this code? I'll try to explain the problem below.
I have a db_connection.php wich includes the following (just my db info and don't worry, i am just using it locally):
<?php
try {
$db = new PDO('mysql:host=localhost;dbname=webappeind;charset=utf8','root','');
}
catch(PDOException $e) {
echo $e->getMessage();
}
?>
But the problem is i have the following file that also includes my db info, but i do not know how to reorganize my code to get it working with my separate php file.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "webappeind";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
$sql = "SELECT * FROM zoekopdrachten ORDER BY titel DESC LIMIT 3";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output gegevens van elke rij
while($row = $result->fetch_assoc()) {
echo "<div class='recenttoegevoegd'>"."<a href='#'>".$row["titel"]."</a>"."</div>";
}
} else {
echo "0 resultaten";
}
?>
You can put the connection information in a separate file called, say, conn.php where you mention the code related to database opening, including credentials. Then, in the calling file, say putdata.php, you use the "require" or "require_once" command to include that conn.php. Let the conn.php file return a connection. Somewhat like this :
<?php
function GetMyConn() {
$server_name = "localhost";
$db_name = "db_name_goes_here";
$db_user = "user_name_goes_here";
$db_pass = "password_goes_here_muahhhaa";
$db_full_addr = "mysql:host=" . $server_name . ";" . "dbname=" . $db_name;
$MyConn = new PDO($db_full_addr, $db_user, $db_pass);
$MyConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $MyConn;
}
?>
In the calling file, you would say, something like :
require_once "GetConn.php";
$MyConnHere = GetMyConn();
$SqlHere = "Sql Statemetn goes here...."
$SqlHere2 = $MyConnHere->prepare($SqlHere);
$SqlHere2->execute();
Also, I suggest you can download the source code of some open source PHP application, such as mantissa, and see how they have organized their code files, folders and settings.

load default image if database connection fails

I am attempting to build a database driven site whereby images are loaded via a php script like so;
<img src="get_image.php?holderID=2">
I can get images to load from a folder outside the root directory when the database is accessible but I also want to be able to load a default image if there is a failure with making the database connection. The DB connection is initiated form a separate php connection file mysqli_template_connect.php;
DEFINE('DB_USER', 'someusername');
DEFINE('DB_PASSWORD', 'amnesia');
DEFINE('DB_HOST', 'localhost');
DEFINE('DB_NAME', 'template');
$dbc = #mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
and then config.inc.php sets some constants, one of which is for all DB connections;
define('MYSQL', '../../../dbconnect/mysqli_template_connect.php');
The get_image.php file then has a database connection conditional;
require('includes/config.inc.php');
REQUIRE(MYSQL);
$holderID = $_GET['holderID'];
if(!$dbc){
$image_name = 'img/unavailable.png';
$info = getimagesize($image_name);
header("Content-Type: {$info['mime']}\n");
readfile($image_name);
}
else {
$query = "SELECT imageID FROM image_holder WHERE image_holderID = $holderID ";
$result = #mysqli_query($dbc, $query);
$number_rows = mysqli_num_rows($result);
if ($number_rows == 1) {
$row = mysqli_fetch_array($result, MYSQLI_NUM);
$imageID = $row[0];
}
else {
$imageID = FALSE;
}
if ($imageID) {
$query = "SELECT file_name FROM image WHERE imageID = $imageID";
$result = mysqli_query($dbc, $query);
$number_rows = mysqli_num_rows($result);
if ($number_rows == 1) {
$row = mysqli_fetch_array($result, MYSQLI_NUM);
$image_name = '../../../uploads/' . $row[0];
}
else {
$image_name = 'img/unavailable.png';
}
}
else {
$image_name = 'img/unavailable.png';
}
$info = getimagesize($image_name);
header("Content-Type: {$info['mime']}\n");
readfile($image_name);
mysqli_close($dbc);
}
If I disable the MYSQL database in XAMP, the default image unavailable.png will not load even though the header and readfile section of code is virtually the same in the section of code that does work. I'm quite a newbie to all this so any ideas on loading the default image would be appreciated.
Depending on the database object you are using (MySQLi/PDO/etc), you can check if they connected. PDO returns a boolean that you can run against.
Since PDO is the most popular, I will provide an example of that. If you use something else, feel free to comment and I can clarify.
$connected = true;
if (!extension_loaded('PDO'))
{
$connected = false;
}
if (!extension_loaded('pdo_mysql'))
{
$connected = false;
}
try
{
$pdo = new PDO("mysql:host={$host};dbname={$db}", $user, $pass);
}
catch(PDOException $e)
{
$connected = false;
}
if(!$connected){ /* Load default image */ }
Note: just make sure you use the correct image headers.
Instead of
$dbc = #mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
Use
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
hopefully it should work..
I have similar code that do the almost the same thing.
I suspect it was the header, since I have a bit more info added to the header. No harm for you to try out.
header('Content-Description: File Transfer');
header('Content-Type: '. $file_content_type);
header('Content-Length: ' . filesize($file_full_path));
header('Content-Disposition: inline; filename=' . $file_name);
readfile($file_full_path);

PHP and MySQL Nested database connection

This is a general example.
The application has 3 files.
conn.inc.php -- setting up the database connection
<?php
$db_host = "localhost";
$db_username = "root";
$db_pass = "";
$db_name = "hmt";
$conn = new mysqli($db_host, $db_username, $db_pass, $db_name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
func.inc.php -- file including functions
<?php
function load_module($module_name){
$sqlCmd = "SELECT content FROM modules WHERE name='$module_name' LIMIT 1";
$result = $conn->query($sqlCmd);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$module_footer = $row["content"];
}
}else {
echo 'Error while loading module '.$module_name;
}
return $result;
$result->free_result();
}
?>
index.php -- the main page to display content
<?php
include 'conn.inc.php';
include 'func.inc.php';
if (!isset($_GET['page_name'])) { // if page_name is not set then reset it to the homepage
$page_name = 'module_footer';
}else{
$page_name = $_GET['module_footer'];
}
$module_content = load_module($page_name);
echo $module_content;
?>
Now my goal was to include functions inside the func.inc.php file and database into conn.inc.php, so as to keep separate and easier to read in the future.
My problem now is that the $conn variable declared in conn.inc.php cannot be used inside the function and it can't get my head around how to use it. I even tried using GLOBALS with no success.
The error for the files is this:
Notice: Undefined variable: conn in ./func.inc.php on line 4
Fatal error: Call to a member function query() on a non-object in ./func.inc.php on line 4
Which (I assume) is because the $conn variable is not in a global scope.
Now my question is. How can I keep the nested files but have the functions working? Is there a mistake in my approach or is it not possible to use a nested call to a mysql object?
Eventually you'll want to get into object-oriented coding but for now lets make what you have a little prettier.
When including files, you'll want to avoid things like global variables. They sound great, but end up being a pain when handling scope. So instead include a set of functions to call.
conn.inc.php
function getConnection(){
$db_host = "localhost";
$db_username = "root";
$db_pass = "";
$db_name = "hmt";
$conn = new mysqli($db_host, $db_username, $db_pass, $db_name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
return $conn;
}
Then function.inc.php
<?php
function load_module($module_name){
$sqlCmd = "SELECT content FROM modules WHERE name='$module_name' LIMIT 1";
//Here is where we get our database connection.
$conn = getConnection();
$result = $conn->query($sqlCmd);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$module_footer = $row["content"];
}
}else {
echo 'Error while loading module '.$module_name;
}
return $result;
$result->free_result();
}
And finally finish up with your index page the way it is. So now, any page that wants a database connection will need to include the conn.inc.php and simply call getConnection() to get a mysqli connection object.
Think of your program as being a series of individual functions working together. And eventually you'll get to it being a series of objects working together. Nothing should be just floating off in global space. Try to encapsulate everything in some sort of function or object to be called over and over with consistent results.
You'd have to do something like this:
$conn = '';
function connect() {
global $conn;
... do db stuff
}
But this is usually bad practice. A more common method is to use a singleton object to "carry" your db handle, and you new that singleton everywhere you need to do DB operations.
function do_something() {
$conn = new DBSingleton();
... do db stuff
}

How to avoid including login credentials on each php page, storing the credentials in a single page and adjusting code to match adjustments

I have the following code to do a simple image upload and store a few data, however I want to remove the section(s) of the code that have the direct database username password and host, with a simple include("config.php") in the heading. So what I am asking apart from the include("config.php") line how would I make adjustments to the code example:$conn = $db->prepare($query); an so on
<?php
include("config.php");
define('UPLOAD_PATH', $_SERVER['DOCUMENT_ROOT'] . 'photohandling/uploads/');
define('DISPLAY_PATH', '/photohandling/uploads/');
define('MAX_FILE_SIZE', 2000000);
$permitted = array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif','image/tiff');
$dames2=time();
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'password';
$db_name = 'test';
if (!empty($_POST)){
$fileName = $_FILES['userfile']['name'];
$tmpName = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
$fname=$_POST['fname'];
$lname=$_POST['lname'];
$age=$_POST['age'];
$acquirer_bin=$_POST['acquirer_bin'];
$terminal_id=$_POST['terminal_id'];
$trace_id=$_POST['trace_id'];
// get the file extension
$ext = substr(strrchr($fileName, "."), 1);
// generate the random file name
$randName = md5(rand() * time());
// image name with extension
$myfile = $acquirer_bin.$trace_id.$dames2.$randName . '.' . $ext;
// save image path
$path = UPLOAD_PATH . $myfile;
if (in_array($fileType, $permitted) && $fileSize > 0 && $fileSize <= MAX_FILE_SIZE) {
//store image to the upload directory
$result = move_uploaded_file($tmpName, $path);
if (!$result) {
echo "Error uploading image file";
exit;
} else {
$db = new mysqli("localhost", "root", "hynes21", "test");
if (mysqli_connect_errno()) {
printf("Connect failed: %s<br/>", mysqli_connect_error());
}
$query =
"INSERT INTO tester(fname,lname,age, acquirer_bin, terminal_id, trace_id,photo_name, size, type, file_path) VALUES(?,?,?,?,?,?,?,?,?,?)";
$conn = $db->prepare($query);
if ($conn == TRUE) {
$conn->bind_param("ssiisisiss",$fname,$lname,$age,$acquirer_bin,$terminal_id,$trace_id, $myfile, $fileSize, $fileType, $path);
if (!$conn->execute()) {
echo 'error insert';
} else {
echo 'Success!<br/>';
echo '<img src="' . DISPLAY_PATH . $myfile . '"/>';
}
} else {
die("Error preparing Statement");
}
}
} else {
echo 'error upload file';
}
} else {
echo 'error';
}
?>
You really shouldn't define database credentials in code. A solid why to do this is to use a configuration file. PHP provides a built in function called parse_ini_file that is perfect for retrieving data from config files (in a certain format ofc).
Here is an example of a ini file that can be parsed by parse_ini_file [docs]
[db]
host = localhost
user = root
pass = password
database = test
As you can see the format of the file is very similar to the php.ini file.
Keep this db.ini file in a place that is not accessible by the web server but can be read by PHP.
Here is a function that can utilize the data in the ini file and create a new mysqli object for you.
// somefile.php
function new_db() {
$info = parse_ini_file('db.ini', true);
return new mysqli($info['db']['host'],
$info['db']['user'],
$info['db']['pass'],
$info['db']['database']);
}
To use your new_db function.
require_once 'somefile.php';
$db = new_db();
$stmt = $db->prepare($query);
// ...
If I understand correctly, you want to use the values defined in config.php. If so, this is all you need to do:
config.php
define(DB_HOST, 'localhost');
define(DB_USER, 'root');
define(DB_PASS, 'hynes21');
define(DB_NAME, 'test');
php file from where config.php is included
Option 1:
$db_host = DB_HOST;
$db_user = DB_USER;
$db_pass = DB_PASS;
$db_name = DB_NAME;
$db = new mysqli($db_host, $db_user, $db_pass, $db_name);
Option 2:
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
And yeah, a heap of ppl will tell you to use PDO instead of mysqli. Indeed you should, but that's doesn't give you an answer to your question :)
Let's say in your config.php file you have this:
$dbHost = 'localhost';
$dbUser = 'root';
$dbPass = 'hynes21';
$dbName = 'test';
Then in your code above you would replace this line:
$db = new mysqli("localhost", "root", "hynes21", "test");
with this:
$db = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
and the rest of your code should just work, thanks to variable scoping.
You could also put the db connection in the config.php file as well, which would allow you to destroy the stored connection info variables so they wouldn't be hanging around anywhere for accidental output:
$dbHost = 'localhost';
$dbUser = 'root';
$dbPass = 'hynes21';
$dbName = 'test';
$db = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
unset($dbHost);
unset($dbUser);
unset($dbPass);
unset($dbName);
This would mean every page load would have the overhead of calling mysqli(), even if that page didn't use the database. But if you have a data driven site then virtually every page will want to call mysqli() anyway so that's not such a big deal.
Later on you may want to look in to using a database wrapper so you don't have to store your DB connection in a locally scoped variable, but this approach will work just fine for simple applications.

Changing a global MySQL db file to MySQLi db file from PHP 4 to PHP 5.4

I have always used the following for MySQL database connection for procedural coding not OO running on PHP 4 and now I am moving some old websites to PHP 5.4:
<?php
global $db_user;
global $db_pass;
global $db_host;
global $db_name;
$db_user = 'USERNAME';
$db_pass = 'PASSWORD';
$db_host = 'HOST';
$db_name = 'DBNAME';
function do_query ( $sql )
{
global $db_user;
global $db_pass;
global $db_host;
global $db_name;
mysql_pconnect( $db_host, $db_user, $db_pass )or die("Cant connect to $db_host: ");
mysql_select_db( $db_name )or die("Cant select $db_name: ");
$res = mysql_query( $sql )or die("You messed up in your sql Using <b>$sql</b>\n\r" . mysql_error());
return $res;
}
?>
How can I change this to work with PHP 5.4 as all that is required for my website is to change this file as everything else now is up to date and the current way I connect with MySQLi never output errors the same way?
Thanks in advance.
UPDATE:
I tried the following:
<?php
$db_user = 'USERNAME';
$db_pass = 'PASSWORD';
$db_host = 'HOST';
$db_name = 'DBNAME';
function do_query ( $sql )
{
mysqli_connect( $db_host, $db_user, $db_pass )or die("Cant connect to $db_host: ");
mysqli_select_db( $db_name )or die("Cant select $db_name: ");
$res = mysqli_query( $sql )or die("You messed up in your sql Using <b>$sql</b>\n\r" . mysqli_error());
return $res;
}
?>
And use a mysqli_close(); at the end but it still doesn't work.
I also tried using it procedurally with:
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
if (!$link) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
But I can't seem to make that work as a function.
I have done loads of tests with different versions but I didn't want to over fill the page with information most people already know so I just put up the original code I have used in the past as I have so many other variations I have tried. I was not just trying to pass the buck, just trying to explain what exactly I was trying to convert to MySQLi. Sorry if people think this is pointless but I am stuck. Thanks.
Three flaws in one post.
First, using a function to create a connection and then query is a bad idea.
Second, you're using a persistent connection. So even when the page is done the connection remains. You'll exhaust your pool of database connections like that.
Third, you're using mysql_ functions, which are deprecated.
So here's the preferred way to do things now, using mysqli and an object approach. I don't recommend $GLOBALS normally but it sounds like you're working with legacy code
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
function do_query($sql) {
$mysqli = $GLOBALS['mysqli'];
$res = $mysqli->query($sql)or die("You messed up in your sql Using <b>$sql</b>\n\r" . mysqli->error);
return $res;
}

Categories