I'm having this weird problem right now, I'm just working on a small admin backend thing that will allow users to upload a file and download it again, simple stuff.
I'm using PHP OOP with Classes and functions and things. Still pretty new at it. Currently on one page I have a "getRecentLinks" function that will call information from a couple tables and put it all out on the page in a table, it works just fine. One of the options on this page is to download the file that was uploaded to that individual row. So I just want it to be a link you click on to say, file-download.php?id=3.
Now on file-download.php I'm currently just testing to get the information on the page before I add the headers and things in there. So I just have a simple
$l = new Links();
$file = $l->getFileInfo($_GET['id']);
print_r($file);
this SHOULD just return information from the database, id, name of file, size, data, and mimetype.
Now this doesn't work. I have no idea why but it doesn't.
Now on my page where I have the getRecentLinks() function it works just fine. I even brought in the getRecentLinks() into my file-download.php page so it's setup like this.
$l = new Links();
$l->getRecentLinks();
$file = $l->getFileInfo($_GET['id']);
print_r($file);
This works just fine and dandy, The second I remove getRecentLinks() it stops calling information from getFileInfo() and I cannot figure it out. I mean it's not a huge deal i could just keep #l->getRecentLinks() there but I can see this getting annoying if I have to add it to every page I want to do something, I'm just at the start of this project.
Here's the code in the Links class
public function getFileInfo($id)
{
$result = $this->runQuery("SELECT * FROM file WHERE id ='".mysql_real_escape_string($id)."'");
$resultSet = $this->fetch($result);
return $resultSet;
}
and
public function getRecentLinks()
{
$result = $this->runQuery("SELECT * FROM links ORDER BY date DESC");
while($j = $this->fetch($result))
{
$resultSet[] = $j;
}
return $resultSet;
}
And heres my connections and fetch functions a friend helped me develop
public function runQuery($sql) {
$this->connection = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass);
if(!$this->connection) {
die("MySQL is down.");
} else {
mysql_select_db($this->dbname);
}
$result = mysql_query($sql,$this->connection) or die(mysql_error());
return $result;
}
public function fetch($result)
{
$resultSet = mysql_fetch_assoc($result);
return $resultSet;
}
mysql_real_escape_string requires a connection. Since getRecentLinks opens a connection it works. But you call mysql_real_escape_string before runQuery (in execution order) in getFileInfo. In this case, I assume the id is an integer, so you're better off and a lot cheaper to call intval($_GET['id']).
Related
I'm on an app that retrieve datas (a 7k lines CSV formated string) from an external server to update my own entity. Each row is an item in a stock.
Today the job is nicely done but it's very very very slow: more than 60s (prod env) to retrieve datas, push it in a 2D array, update the BDD, and finally load a page that display the bdd content.
When only displaying the page it's about 20s (still prod).
This the profiler's timeline result while only displaying records : Symfony's profiler timeline
Anymore, i'm not able to profile the "updateAction" cause i't don't appear in the last ten request list.
2 days ago I was checking each row of the CSV file to add it only if needed, I was soft-deleting items to restore it later when back in the stock etc. but with that speed I tried many things to have normal performances.
At the begening everything was in the controler, I moved the function that add/remove in a dedicated service, then in the repository to finally get it back in my controler. To have decent results I tried to empty the database and then refill it without checking. First, using LOAD DATA LOCAL INFILE but it is not compatible with my table pattern (or I mis understood something) and now I'm simply emptying the table before filling it with the CSV (without any control). The time score I gave earlier was with this last try (which is the best one).
But enought talk
here is my controler:
public function majMatosClanAction()
{
$resMaj = $this->majClanCavernes();
if ($resMaj === NULL)
{
$this->get('session')->getFlashBag()->add('alert-danger', 'Unidentified');
return $this->redirect($this->generateUrl('loki_gbl'));
} else if ($resMaj === FALSE)
{
$this->get('session')->getFlashBag()->add('alert-warning','password update required');
return $this->redirect($this->generateUrl('loki_gbl_ST'));
} else
{
$this->get('session')->getFlashBag()->add('alert-success','success');
return $this->redirect($this->generateUrl('loki_gbl_voirMatosClan'));
}
}
here is the function that my controller call:
public function majClanCavernes()
{
$user = $this->get('security.token_storage')->getToken()->getUser();
$outils = $this->container->get('loki_gbl.outils');
if ($user !== NULL)
{
$pwd = $user->getGob()->getPwd();
$num = $user->getGob()->getNum();
if($outils->checkPwd($num, $pwd) !== TRUE) return FALSE;
$em = $this->getDoctrine()->getManager();
//This is a temporary solution
//////////////////////////////////////////////
$connection = $em->getConnection();
$platform = $connection->getDatabasePlatform();
$connection->executeUpdate($platform->getTruncateTableSQL('MatosClan', true ));
//////////////////////////////////////////////
$repository = $em->getRepository('LokiGblBundle:MatosClan');
$urlMatosClan = "http://ie.gobland.fr/IE_ClanCavernes.php?id=".$num."&passwd=".$pwd;
//encode and format the string via a service
$infosBrutes = $outils->fileGetInfosBrutes($urlMatosClan);
//$csv is a 2D array containing the datas
$csv = $outils->getDatasFromCsv($infosBrutes);
foreach($csv as $item)
{
$newItem = new MatosClan;
$newItem->setNum($item[0]);
$newItem->setType($item[1]);
[...]
$em->persist($newItem);
}
$em->flush();
return TRUE;
}
else{
return NULL;
}
}
What is wrong? 7k lines is not that big!
Could it be a lack of hardware issue?
Check out doctrine's batch processing documentation here.
You can also disable logging:
$em->getConnection()->getConfiguration()->setSQLLogger(null);
I have created a function to run an SQL query, output the data and that seems fine, Problem is I can't do anything with it now since i can't make the output to the templates work.
PHP Code:
function getCategories() {
try {
foreach($this->pdo->query("SELECT categories.cat_id, categories.cat_name, categories.cat_description FROM categories") as $row) {
$rows[] = $row;
}
} catch(PDOException $e) {
print "Error!:" . $e->getMessage();
return false;
}
return $rows;
$smarty = new Smarty();
$smarty->assign('categories', $rows);
}
Which simply returns this:
Replacing return $rows; with return $smarty->assign('categories', $rows); simply renders a blank page.
I'm using this in the template: {$categories.cat_name}
Can anyone help me fix this?
I'm trying to rewrite a vulnerable crappy forum script using Smarty so it's a base worth trying to develop a script off of. It's literally just categories, topics and a login / register system atm that I'm trying to rewrite using Smarty.
The problem is that you create a new smarty object, assign it a variable, but doesn't use it to display your template - so this object get lost.
I suggest to pass the Smarty object to your function like this:
function getCategories(&$smarty) {
$rows = array();
if($result = $this->pdo->query("SELECT categories.cat_id, categories.cat_name, categories.cat_description FROM categories")) {
$rows = $result->fetchAll();
}
$smarty->assign('categories', $rows);
}
This way the object reference will be passed to the function - you will be able to assign any vars you want to it without the need of returning it. Just be sure that you send the Smarty object you use to render the template.
So I have the following php-script test.php:
<?php
class Database {
public $databaseConnection;
function __construct(){
$this->databaseConnection = new PDO('sqlite:test.sq3', 0, 0);
$this->databaseConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::query('CREATE TABLE...');
}
function query($sql, $params = NULL){
...
}
function insert($table, $data){
...
}
}
$database = new Database();
$database->insert(...);//insert something into Database
$userData = $database->query(...);//getting $userData after query
$username = $userData;
print_r($username);
$database = null;
unlink('test.sq3');
So everythings working fine until the last line.
Permission denied in F:\...\test.php on line 75
I already looked up following things in the documentation:
Instruction separation:
http://php.net/manual/en/language.basic-syntax.instruction-separation.php
Connections and Connection management (of PDO-objects):
http://php.net/manual/en/pdo.connections.php
So to end the connection of a PDO-ocject to the database it has to set = null.
After that I tried:
unset($database);
Permission denied. So I made an extern file delete.php:
<?php unlink('test.sq3'); ?>
This script is working. So I can delete the file in another script.
And the last thing I tried (with =null and unset()):
include('delete.php');
Which did not work neither. But the main thing about is that I don´t have a clue why I can´t delete the file in the same script.
So how can I delete the database-file in the same script?
So now I find out whats wrong. In the method query which looked like:
function query($sql, $params = NULL){
$s = $this->databaseConnection->prepare($sql);
if(is_array($params)){
$s->execute(array_values($params));
return $s;
}
$s->execute((array) $params);
return $s;
}
As you can see there is no fetch()-statement, because I wanted to try out whats happen without it. So you get an Output just like:
PDOStatement Object ( [queryString] => SELECT username FROM user WHERE numberoflogins = ? )
I skipped it because I thought it wasn´t really necessary when it works.
Well, atleast I don´t have a clue whats this PDO method has something todo with the end of my script because I unset every variable which has something todo with the PDO object but the point is that now he deletes the file.
I have a function which is using recursion to call itself and I need to know the correct syntax for calling itself.
Note: I am using Object oriented programming technique and the function is coming from a class file.
Below is my function
// Generate Unique Activation Code
//*********************************************************************************
public function generateUniqueActivationCode()
{
$mysql = new Mysql();
$string = new String();
$activation_code = $string->generateActivationCode();
// Is Activation Code Unique Check
$sql = "SELECT activation_id FROM ". TABLE_ACTIVATION_CODES ." WHERE activation_code='$activation_code' LIMIT 1";
$query = $mysql->query($sql);
if($mysql->rowCount($query) > 0)
{
// This function is calling itself recursively
return generateUniqueActivationCode(); // <- Is this syntax correct in Oops
}
else
{
return $activation_code;
}
}
Should the code to call it recursively be
return generateUniqueActivationCode();
OR
return $this->generateUniqueActivationCode();
or if something else other than these 2 ways.
Please let me know.
You would need to call it with the $this variable since your function is part of the instance. So:
return $this->generateUniqueActivationCode();
PS: Why not just try both methods and see if it generates any errors?
Recursion is the COMPLETELY WRONG WAY TO SOLVE THIS PROBLEM
Unlike iteration you're filling up the stack, and generating new objects needlessly.
The right way to solve the problem is to generate a random value within a scope which makes duplicates very unlikely, however without some external quantifier (such as a username) to define the scope then iteration is the way to go.
There are further issues with your code - really you should be adding records in the same place where you check for records.
I am using Object oriented programming technique and the function is coming from a class file
Then it's not a function, it's a method.
And your code is susceptibale to SQL injection.
A better solution would be:
class xxxx {
....
public function generateUniqueActivationCode($id)
{
if (!$this->mysql) $this->mysql = new Mysql();
if (!$this->string) $this->string = new String();
$limit=10;
do {
$activation_code = $string->generateActivationCode();
$ins=mysql_escape_string($activation_code);
$sql="INSERT INTO ". TABLE_ACTIVATION_CODES ." (activation_id, activation_code)"
. "VALUES ($id, '$ins)";
$query = $mysql->query($sql);
if (stristr($query->error(), 'duplicate')) {
continue;
}
return $query->error() ? false : $activation_code;
} while (limit--);
return false;
}
} // end class
I have project developed using cakephp which is getting data from different DBs, but if one of theses database some pages not open and give me the following error :
Database table tablenae for model moedlname was not found.
..and I have in this page other data displayed from the other database which work probably.
how i can determine if database is offline using cake and i can make this model read from another place like a cache file until the database startup again.
Perhaps a better approach is to cache results and read from the cache, only hitting the DB when needed...
<?php
$cacheKey = 'myCacheNumber1';
if (($data = Cache::read($cacheKey)) === false) {
$data = $this->Model->find('all');
if ($data) {
Cache::write($cacheKey, $data);
}
}
?>
The problem with this is it assumes the model and database connection are available for the time when the cache doesn't exist (or has expired), and if it wasn't, you'd still get the same errors, but the frequency would certainly be reduced.
I think to test if the DB is available at all would require some custom code trickery since the cake core method of connecting assumes success and fails heavily when not available. I'd probably make a component with standard PHP connect methods to control if you should attempt to load a model.
<?php
$cacheKey = 'myCacheNumber1';
if (($data = Cache::read($cacheKey)) === false) {
if ($this->DbTest->check('hostname','username','password')) {
$data = $this->Model->find('all');
if ($data) {
Cache::write($cacheKey, $data);
}
}
}
?>
<?php
// app/controllers/components/db_test.php
class DbTestComponent extends Object {
function check($hostname,$username,$password) {
$result = true;
$link = #mysql_connect($hostname,$username,$password);
if (!$link) {
$result = false;
}
#mysql_close($link);
return $result;
}
}
?>