Cakephp - detect if unable to connect to database and recover gracefully - php

I have a few sites built with Cakephp. If any of these sites lose their connection to the database for whatever reason it does not handle it well. Basically it renders itself inside itself trying to display an error over and over until the browser crashes. The rendering itself inside itself is caused by the use of requestAction from elements.
What I want to know is how can I check if the database connection exists
I tried this in the app_controller before filter:
if(!ConnectionManager::getDataSource('default'))
{
die(); //this will be a message instead
}
but it does not seem to work.
Thanks

Use the following code:
<?php
$filePresent = true;
if (!file_exists(CONFIGS.'database.php')):
echo '<span class="notice-failure">Database configuration file is not present. Please contact admin#website</span>';
$filePresent = false;
endif;
if ($filePresent!=false):
uses('model' . DS . 'connection_manager');
$db = ConnectionManager::getInstance();
#$connected = $db->getDataSource('default');
if (!$connected->isConnected()):
echo '<p><span class="notice-failure">Not able to connect to the database. Please contact admin#website</span></p>';
endif;
endif;
?>
Here I'm printing messages (in those tags). You can replace the echo line with die().

(Cakephp 3.x)
Just follow the example given in PagesController's Home view:
Basically it is:
use Cake\Datasource\ConnectionManager;
try {
$connection = ConnectionManager::get('yourconnection');
$connected = $connection->connect();
} catch (Exception $connectionError) {
//Couldn't connect
}
//connected

Related

Phalcon: How to use Phalcon\Debug, but control the output for development/production environment?

I have a small application on the specified framework. I want to control what the user sees if my application fails. This should not be a standard web server response, which it is differently displayed by different browsers. In this regard, I want to use Falcon\Debug. But, as far as I understand, this component of the framework will always show something like this:
However, I would like to show this information only if debugging is enabled in my application (using an environment variable, for example). In other cases I would like to show just a page describing the error.
Question: how to implement this?
This is my implementation in the index.php file:
try {
$root = str_replace('\\', '/', dirname(dirname(__FILE__))) . '/';
require_once $root . 'apps/Bootstrap.php';
$bootstrap = new Bootstrap();
$bootstrap->run();
} catch (\Exception $e) {
if (DEV_MODE === true) {
$debug = new \Phalcon\Debug();
die($debug->listen()->onUncaughtException($e));
} else {
header('HTTP/1.1 500 Internal Server Error');
// Your fancy error page for users here!
die();
}
}
The idea is to have a variable somewhere in your config files which you can easily switch between true/false.
Update!
You can add this too:
if (DEV_MODE === true) {
error_reporting(E_ALL);
ini_set('display_errors', 1);
} else {
error_reporting(0);
}
Complementing the proposal solution by Nikolay Mihaylov, maybe you want to redirect to a specific view and so not show blank page or default error 500 in browser, thereforce, only need add the NameSpace at the beginning
use Phalcon\Http\Response
and redirect in catch block, here a little example:
try {
// some code
} catch (\Exception $e) {
// ... some code
$response = new Response();
// Redirect...
$response->redirect('controller/view'); // for example, you could create a view to show error 500
// Send response to the client
$response->send();
}

Nothing is being returned

So, now, I can't seem to get this to work. What I'm trying to accomplish is to get the success message to show up, but it just doesn't work for some odd reason.
I'm using the php-login project (minimal) available here: http://www.php-login.net/
This is the basic PHP part.
<?php
//die(print_r(get_defined_vars(), true));
include("includes/database.incl.php");
require_once("includes/Login.php");
$login = new Login();
if (isset($login)) {
if ($login->errors) {
if ($login->messages) {
foreach ($login->messages as $message) {
die("success");
}
}
foreach ($login->errors as $error) {
echo $error;
}
}
} else {
echo "nope";
}
$login = null;
?>
Right now, I'm using a program to send login details (log_name, log_password) using a POST request. It works and echos the errors if I deliberately put in wrong details, but once I type the details, it returns nothing. Even if I type incorrect details after, it still presents me with nothing.
Thanks in advance.
It turns out that it was a web server problem.
I was originally using XAMPP, and now that I switched to WAMP, it works.
Thanks for the help, everyone.

a link to server could not be established

i write this code in Database class ...
public function DeleteArticle($list)
{
$this->setdata("DELETE FROM Article WHERE Code IN (" . implode(',', $list) . ")");
}
private function connect()
{
mysql_connect('localhost' ,'#######' ,'########' );
mysql_select_db('allatala_db');
}
public function setdata($query)
{
$this->connect();
mysql_query($query);
mysql_close();
}
and call it in my adminpage.php
if(isset($_POST['delete1']))
{
$obj=new Database();
$obj->DeleteArticle($_POST['checkbox']);
}
so... in my localhost server work it properly but in the server i have this problem
a link to server could not be established
Help me plz
Your code has no error so there is some minor mistake.
Just make sure of following things.
1) Your server is running, Also try to open phpmyadmin in browser.
2) Open phpmyadmin and check your username and password under utilities.
3) User which you have created must have rights which is needed.
I think your problem would be solve after checking this things.

How can check a php file is successfully included?

I want to check if 'dbas.php' is included in 'ad.php'. I wrote the code -
ad.php
<?php if(file_exists("dbas.php") && include("dbas.php")){
// some code will be here
}
else{echo"Database loading failed";}
?>
I successfully tested the file_exists() part but don't know if the include() will work well or not, cause I tried in localhost and if the file is in directory then it never fails to include. So I don't know how this code would behave in the server if much traffic be there. So please tell me is my code correct ?
-Thanks.
Solved: Thank you so much for your answers.
Using php's require method is more suitable if you want to be absolutely sure that the file is included. file_exists only checks if the file exists, not if it's actually readable.
require will produce an error if inclusion fails (you can catch the error, see Cerbrus' answer).
Edit:
However, if you don't want the script to halt if the inclusion fails, use the method is_readable along with file_exists, like:
if( file_exists("dbas.php") && is_readable("dbas.php") && include("dbas.php")) {
/* do stuff */
}
Simply use require:
try {
require 'filename.php';
} catch (Exception $e) {
exit('Require failed! Error: '.$e);
// Or handle $e some other way instead of `exit`-ing, if you wish.
}
Something that wasn't mentioned yet: you could add a boolean, like:
$dbasIncluded = true;
In your dbas.php file, then check for that boolean in your code. Although generally, if a file doesn't include properly, you'd want php to hit the brakes, instead of rendering the rest of the page.
file_exists("dbas.php") Is doing the checking. If it exists, then do the include.
if(file_exists("dbas.php"){
include("dbas.php")
//continue with you code here
}
Put your functionality in a function and use function_exists to check if it is there.
include ("php_file_with_fcn.php");
if (function_exists("myFunc")) {
myFunc();
// run code
} else {
echo "failed to load";
}
In your case, the incusion file would be
function db_connect() {
$user = "user";
$pass = "pass";
$host = "host";
$database = "database";
mysql_connect($host, $user, $pass);
return mysql_select_db($database);
}
and the main file:
include("db_connect.php");
if (function_exists("db_connect")) {
if (db_connect() === TRUE) {
// continue
} else {
// failed to connect (this is a different error than the "can't include" one and
// actually **way** more important to handle gracefully under great load
}
} else {
// couldn't load database code
}
Use this code instead of your code, because in your code if file is not exist in server then php errors arise and that is not good so use this code:
if(file_exists("dbas.php")) {
include_once("dbas.php");
} else {
echo"file is not found";
}
This code means if file exists on server then function include else file is not found echo.
write
echo "file is includ"
at the end of "dbas.php"

How to print function result, if worked print -- yes, else ERROR

I am writing a small data entry form. Data gets entered in html form by user & then into csv file on server. Consider the following snippet, that i wrote to do this
if(!empty($_POST)) {
$handler = fopen('database.csv','a') or exit("Error: Unable to open file!");
fputcsv($handler,$_POST);
fclose($handler);
}
?>
Pretty simple!
The only "fancy" task is display a message to confirm that the entry has been added to the database(Entry added), clearing the form ready for the next entry. Or incase of error, display error message(Doh! Write failed ). I can use OR statement but that would only be invoked incase of an error.
Any idea how to do this?
[UPdate]
Thanks for excellent replies everyone! I added conditional statement as everyone suggested
if(!empty($_POST)) {
$handler = fopen('database.csv','a') or exit("Error: Unable to open file!");
if(fputcsv($handler,$_POST)) {
echo 'everything okay, add next record';
}
else {
exit('Error: Record add failed. Try again or contact admin');
}
fclose($handler);
}
if(!empty($_POST)) {
$handler = fopen('database.csv','a');
if ($handler === FALSE) {
exit("Error: Unable to open file!");
} else {
fputcsv($handler,$_POST);
fclose($handler);
echo "everything A-ok";
}
}
You can include a 3-state switch that:
) does data entry and re-displays the cleared form;
) displays the error and re-populates the form so user can fix it;
) default to no data entry, clear form
Use a post or session variable to specify the action to take, default to no action if the variable is not set or does not validate.

Categories