Check if an existing value is in a database - orm

I was wondering how I would go about checking to see if a table contains a value in a certain column.
I need to check if the column 'e-mail' contains an e-mail someone is trying to register with, and if something exists, do nothing, however, if nothing exists, insert the data into the database.
All I need to do is check if the e-mail column contains the value the user is registering with.
I'm using the RedBeanPHP ORM, I can do this without using it but I need to use that for program guidelines.
I've tried finding them but if they don't exist it returns an error within the redbean PHP file. Here's the error:Fatal error: Call to a member function find() on a non-object in /home/aeterna/www/user/rb.php on line 2433
Here's the code that I'm using when trying this:
function searchDatabase($email) {
return R::findOne('users', 'email LIKE "' . $email . '"');
}

My approach on the function would be
function searchDatabase($email) {
$data = array('email' => $email);
$user = R::findOne('users', 'email LIKE :email, $data);
if (!empty($user)) {
// do stuff here
} // end if
} // end function
It's a bit more clean and in your function

Seems like you are not connected to a database.
Have you done R::setup() before R::find()?
RedBeanPHP raises this error if it can't find the R::$redbean instance, the facade static functions just route calls to the $redbean object (to hide all object oriented fuzzyness for people who dont like that sort of thing).
However you need to bootstrap the facade using R::setup(). Normally you can start using RB with just two lines:
require('rb.php'); //cant make this any simpler :(
R::setup(); //this could be done in rb.php but people would not like that ;)
//and then go...
R::find( ... );
I recommend to check whether the $redbean object is available or whether for some reason the code flow has skipped the R::setup() boostrap method.

Edited to account for your updated question:
According to the error message, the error is happening inside the function find() in rb.php on line 2433. I'm guessing that rb.php is the RedBean package.
Make sure you've included rb.php in your script and set up your database, according to the instructions in the RedBean Manual.
As a starting point, look at what it's trying to do on line 2433 in rb.php. It appears to be calling a method on an invalid object. Figure out where that object is being created and why it's invalid. Maybe the find function was supplied with bad parameters.
Feel free to update your question by pasting the entirety of the find() function in rb.php and please indicate which line is 2433. If the function is too lengthy, you can paste it on a site like pastebin.com and link to it from here.

Your error sounds like you haven't done R::setup() yet.
My approach to performing the check you want would be something like this:
$count = count(R::find('users', 'email LIKE :email', array(':email' => $email)));
if($count === 0)
{
$user = R::dispense('users');
$user->name = $name;
$user->email = $email;
$user->dob = $dob;
R::store($user);
}

I don't know if it is this basic or not, but with SQL (using PHP for variables), a query could look like
$lookup = 'customerID';
$result = mysql_fetch_array(mysql_query("SELECT columnName IN tableName WHERE id='".$lookup."' LIMIT 1"));
$exists = is_null($result['columnName'])?false:true;
If you're just trying to find a single value in a database, you should always limit your result to 1, that way, if it is found in the first record, your query will stop.
Hope this helps

Related

CodeIgniter4 Model returning data results

I am starting to dabble in CI4's rc... trying to get a head of the game. I noticed that the Model is completely rewritten.
Going through their documentation, I need some guidance on how to initiate the equivalent DB query builder in CI4.
I was able to leverage return $this->findAll(), etc...
however, need to be able to be able to query w/ complex joins and also be able to return single records etc...
When trying something like
return $this->orderBy('import_date', 'desc')
->findColumn('import_date')
->first();
but getting error:
Call to a member function first() on array
Any help or guidance is appreciated.
Suppose you have a model instantiated as
$userModel = new \App\Models\UserModel;
Now you can use it to get a query builder like.
$builder = $userModel->builder();
Use this builder to query anything for e.g.
$user = $builder->first();
Coming to your error.
return $this->orderBy('import_date', 'desc')
->findColumn('import_date');
findColumn always returns an array or null. So you can't use it as object. Instead you should do following.
return $this->orderBy('import_date', 'desc')->first();

Parse user input for command arguments into array

I'm making a bot in PHP and I want a better way to parse user input into arguments for later operations.
An example would be a user saying "/addresponse -"test" -"works""
I want this to parse that string into:
$command ["test", "works"];
I have found the PHP command parser but I want the user to be able to use human readable commands rather than typing something like /addresponse?p="test"&r="works"
Right now I have a regex working so the user can type "/addresponse "test" "works"" but there are obvious problems because the user cannot make a response for '"test"' only 'test'
I'd appreciate any help, right now I think I can make a regex to get all text between ' -' but I still don't think this is the best solution.
I just looked into using a regex to find text between ' -"' and while this is better than just between quotes, it doesn't solve the whole problem because it still will break if the input contains ' -"'. A string containing this isn't particularly common but I'd like a solution where almost any input will not break it.
Is this a stupid question? I don't think there is a built in php function for this and it got downvoted with no comment...
I found a partial solution:
function parse_cmd($command) {
$command = explode(' -"', $command);
array_splice($command, 0, 1);
foreach($command as &$element) {
$element = substr($element, 0, strlen($element) -1);
}
return $command;
}
This will split everything after ' -"' and return it as an array

passing msqli to a function - can't suss out why it's not working

I've searched high and low for an answer on this, but I'm either missing something, or I just can't find anything in this context.
Background - trying to avoid spaghetti frenzy with a little casual project I'm starting; part of this will involve mainly just calls to a mysql database, displaying table content and so on. Simply put, like a CRM I guess.
I may be way off base here, but I want to be able to create my sql calls as functions, which will help if/when I tweak and tune, as well as creating a cleaner code for what I'm looking to do.
So, without further ado, I have this as a demomstration:
echo "<table>";
selectall('actions','content',$mysqli);
echo "</table><br><br>";
What this does is show all rows from my table of 'actions. "content" is just an example field name I'm passing through that I want to display, as it is the main human-relevant field name in that table. I'm also passing $mysqli through here for my function db call.
My function looks like this:
function selectall($s_table,$s_content,$mysqli){
$query = "SELECT * FROM " . $s_table;
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
$id = $row['id'];
echo "<tr><td>{$row[$s_content]}</td></tr>";
}
$resource->free();
$mysqli->close();
}
However.... it doesn't work, and it seems to throw a wobbly saying:
Warning: mysqli::query(): Couldn't fetch mysqli
This points to the action within the line $resource = $mysqli->query($query);
I know the function and everything is ok, as if I restate and declare $mysqli within the first line of the function, like so...
$mysqli = new mysqli(username password and so on in here);
... it works spot on.
$mysqli exists and works within the same code that is passing the variable within the function too.
This is early stages, so by shuffling the code around trying to poke the $mysqli pass into life I have perhaps made the code a little messier that intended, so try not to worry too much about that.
Anyone any ideas why it doesn't like this?
D'oh...
I had a
$mysqli->close();
in the lines above. Solved myself.
For reference, this is my function:
function selectall($s_table,$s_field,$mysqli){
if ($mysqli->connect_error) {die('Connect Error (' . $mysqli->connect_errno . ') '. $mysqli->connect_error);}
$s_table = preg_replace('/[^0-9a-zA-Z_]/', '', $s_table); // Cleans up the table name variable
$s_field = preg_replace('/[^0-9a-zA-Z_]/', '', $s_field); // Cleans up the field name variable
$query = "SELECT * FROM " . $s_table; // Adds passed table name to the select all
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
echo "<tr><td>{$row[$s_field]}</td></tr>"; // Content for each row of the select all
}
$resource->free();
$mysqli->close();
}
As you can see, I've also tried to protect the variables that enter the function.
This can be called via:
selectall('actions','content',$mysqli);
In this context, I want to view all the entries in the 'actions' table by the field name 'content'. This function, with some code above and below for a table, will create a new row for each entry.
I'll probably evolve a few, already created on that includes a delete button at the end of the line which is 'selectalldel'.
Open to comments on whether this actually is worthwhile, but thought I'd post up my corrected stupidity in case anyone finds this useful.

How to load objects from sql queries in Joomla 2.5?

Using the Andrew Eddie's tutorials here I am working on building some custom code for menus. Here we go:
$query ->select('id, menutype, title')
->from('#__menu_types')
->where('menutype='.$somemenu);
$db->setQuery($query);
I don't know how to load one object value like I used to do it with Joomla 1.5:
$result = $db->loadObject();
$thetitle = $result->title; // I need this value and I always get error "Notice: Trying to get property of non-object" at this line
How can I SUCCESSFULLY get the value of $thetitle please?
That should work. I see no problem with your code.
The error you are getting is consistent with not having found a match in the database.
Since you do not appear to have any error handling it might even be an SQL error.
Try and add this:
if ($error = $db->getErrorMsg()) {
throw new Exception($error);
}
The correct query is
$query ->select('id, menutype, title')
->from('#__menu_types')
->where('menutype='.$db->quote($somemenu));
$db->setQuery($query);
Now I can get the values of the query correctly.

How can I see CakePHP's SQL dump in the controller?

Is there a way that one can cause CakePHP to dump its SQL log on demand? I'd like to execute code up until a point in my controller and see what SQL has been run.
Try this:
$log = $this->Model->getDataSource()->getLog(false, false);
debug($log);
http://api.cakephp.org/2.3/class-Model.html#_getDataSource
You will have to do this for each datasource if you have more than one though.
There are four ways to show queries:
This will show the last query executed of user model:
debug($this->User->lastQuery());
This will show all executed query of user model:
$log = $this->User->getDataSource()->getLog(false, false);
debug($log);
This will show a log of all queries:
$db =& ConnectionManager::getDataSource('default');
$db->showLog();
If you want to show all queries log all over the application you can use in view/element/filename.ctp.
<?php echo $this->element('sql_dump'); ?>
If you're using CakePHP 1.3, you can put this in your views to output the SQL:
<?php echo $this->element('sql_dump'); ?>
So you could create a view called 'sql', containing only the line above, and then call this in your controller whenever you want to see it:
$this->render('sql');
(Also remember to set your debug level to at least 2 in app/config/core.php)
Source
for cakephp 2.0
Write this function in AppModel.php
function getLastQuery()
{
$dbo = $this->getDatasource();
$logs = $dbo->getLog();
$lastLog = end($logs['log']);
return $lastLog['query'];
}
To use this in Controller
Write : echo $this->YourModelName->getLastQuery();
It is greatly frustrating that CakePHP does not have a $this->Model->lastQuery();. Here are two solutions including a modified version of Handsofaten's:
1. Create a Last Query Function
To print the last query run, in your /app_model.php file add:
function lastQuery(){
$dbo = $this->getDatasource();
$logs = $dbo->_queriesLog;
// return the first element of the last array (i.e. the last query)
return current(end($logs));
}
Then to print output you can run:
debug($this->lastQuery()); // in model
OR
debug($this->Model->lastQuery()); // in controller
2. Render the SQL View (Not avail within model)
To print out all queries run in a given page request, in your controller (or component, etc) run:
$this->render('sql');
It will likely throw a missing view error, but this is better than no access to recent queries!
(As Handsofaten said, there is the /elements/sql_dump.ctp in cake/libs/view/elements/, but I was able to do the above without creating the sql.ctp view. Can anyone explain that?)
In CakePHP 1.2 ..
$db =& ConnectionManager::getDataSource('default');
$db->showLog();
What worked finally for me and also compatible with 2.0 is to add in my layout (or in model)
<?php echo $this->element('sql_dump');?>
It is also depending on debug variable setted into Config/core.php
Plugin DebugKit for cake will do the job as well. https://github.com/cakephp/debug_kit
If you are interested in some specific part of code, you can clear first the log, and then display only queries that happen after that point.
Also note that 'Model' below, is the actual class name, like User, Page etc.
//clear log (boolean $clear = true)
$this->Model->getDataSource()->getLog(false, true);
...
...
...
...
//Show log so far
$log = $this->Model->getDataSource()->getLog(false, false);
debug($log);
exit;