i'm training SOLID/Architectures and trying to make an INSERT on my code, but its insert four times on DB. There's any error on my logic? I'm following Repositories/Service Pattern.
i think my service is executing two times, but i cant find the reason.
Repositorie Code
public function inserirEstoque($dadosPost)
{
if (empty($dadosPost)) {
return false;
}
$pdo = $this->dbConnection->conectar();
$sql = $pdo->prepare('INSERT INTO estoque (nomeProduto, descriptions, price, quantity)
VALUES (:nome, :descriptions, :price, :quantity)');
$sql->bindValue(':nome', $dadosPost['nomeProduto']);
$sql->bindValue(':descriptions', $dadosPost['descriptions']);
$sql->bindValue(':price', $dadosPost['price']);
$sql->bindValue(':quantity', $dadosPost['quantity']);
$res = $sql->execute();
if($res == false)
{
return false;
}
return $res;
}
Service
public function insertEstoque()
{
$db = new MySQL();
$insert = new EstoqueRepositories($db);
if(!empty($insert->inserirEstoque($_POST))){
return $insert->inserirEstoque($_POST);
} else {
return false;
}
}
Controller
public function insert()
{
$insert = new EstoqueService();
$insert->insertEstoque();
header('Location: ../../index.php');
}
It's executing twice because of this
if(!empty($insert->inserirEstoque($_POST))){
return $insert->inserirEstoque($_POST);
} else {
return false;
}
if you wanna check if the POST data is empty just remove where it inserts the data then it should just insert it 1 time
if(!empty($_POST["whatevername"])){
return $insert->inserirEstoque($_POST);
} else {
return false;
}
As an addition to Reed's answer, if you just want to check the result of a function call before carrying on, assign the result to a variable and use that variable.
$res = $insert->inserirEstoque($_POST)
if(!empty($res)){
return $res;
} else {
return false;
}
Related
I'm trying to delete from two tables using one function.
Controller code:
public function userdelete()
{
$u_id = $this->uri->segment(3);
$lr_id = $this->uri->segment(3);
$returndata = $this->user_model->user_delete($u_id, $lr_id);
if($returndata) {
$this->session->set_flashdata('successmessage', 'user deleted successfully..');
redirect('users');
} else {
$this->session->set_flashdata('warningmessage', 'Something went wrong..Try again');
redirect('users');
}
}
Modle code:
public function user_delete($lr_id, $u_id ) {
return $this->db->delete('login_roles',['lr_id'=>$lr_id]);
return $this->db->delete('login',['u_id'=>$u_id]);
}
I'm able to delete only from the first table but not the other one. this is working :
return $this->db->delete('login_roles',['lr_id'=>$lr_id]); but not return $this->db->delete('login',['u_id'=>$u_id]);.
As said in the comment you have to remove the first return.
You should compute the two results :
public function user_delete($lr_id, $u_id ) {
$delete1Response = $this->db->delete('login_roles',['lr_id'=>$lr_id]);
$delete2Response = $this->db->delete('login',['u_id'=>$u_id]);
return ($delete1Response AND $delete2Response);
}
It will returns true only if both are deleted
You even can go further and :
public function user_delete($lr_id, $u_id ) {
$delete1Response = $this->db->delete('login_roles',['lr_id'=>$lr_id]);
$delete2Response = $this->db->delete('login',['u_id'=>$u_id]);
return (object)array('role' => $delete1Response, 'user' => $delete2Response);
}
Then you can access to data like that :
$response = user_delete(...);
if ($response->role AND $response->user) {
// All fine
} else {
// One or both failed.
// Display error or do something
}
It never reaches the second $this->db->delete since its returns after executing the first one. Try:
public function user_delete($lr_id, $u_id ) {
if($this->db->delete('login_roles',['lr_id'=>$lr_id])){
//success, try the next one
return $this->db->delete('login',['u_id'=>$u_id]);
}
//failed
return false;
}
OK, I'm fully expecting someone to come along and tell me I missed something obvious, but I've spent days trying to figure out what's wrong, and I at this point, if someone can point out a stupid mistake, I'll just be glad to solve the problem. I'm just starting to figure out PDO, so I'm guessing the problem is there, but I really don't know.
This is mostly working. It opens, closes, reads, and does garbage collection. It will write, but only the id, not the data. Destroy is not working either, which seems to be related. If I put echo into the functions, the variables are being passed. The queries work when I try them directly. What seems to be happening is that the binding isn't working. I've tried both bindParam and bindValue. I've tried so many other things I can't even list them all. So anyway, here's the class:
class Sessions {
private $id;
private $data;
protected $pdo;
private $maxTime;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
// Set handler to overide SESSION
#session_set_save_handler(
array($this, "openSession"),
array($this, "closeSession"),
array($this, "readSession"),
array($this, "writeSession"),
array($this, "destroySession"),
array($this, "gcSession")
);
session_start();
}
public function openSession()
{
// If successful
if ($this->pdo) {
return true;
} else {
return false;
}
}
public function closeSession() {
// Close the database connection
if ($pdo = NULL) {
#session_write_close();
return true;
} else {
return false;
}
}
public function readSession($id) {
if (isset($id)) {
// Set query
$q = 'SELECT data FROM sessions WHERE id = :id';
$stmt = $this->pdo -> prepare($q);
// Bind the Id
$stmt -> bindValue(':id', $id);
$stmt -> execute();
$r = $stmt -> fetch();
// Return the data
if (!empty($r['data'])) {
return $r['data'];
} else {
// Return an empty string
return '';
}
} else {
return '';
}
}
// when session started and updated
public function writeSession($id, $data) {
// Set query
$q = "INSERT INTO sessions
(id, `data`, startTime)
VALUES (:id, :data, NOW())
ON DUPLICATE KEY UPDATE
`data` = :data2,
startTime = NOW()";
$stmt = $this->pdo->prepare($q);
// Bind data
$stmt->bindParam(':id', $id);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':data2', $data);
$stmt->execute();
if ($stmt->rowCount()) {
return TRUE;
} else {
return FALSE;
}
}// when session started and updated
public function writeSession($id, $data) {
// Set query
$q = "INSERT INTO sessions (id, `data`, startTime) VALUES (:id, :data, NOW()) ON DUPLICATE KEY UPDATE `data` = :data2, startTime = NOW()";
$stmt = $this->pdo -> prepare($q);
// Bind data
$stmt->bindParam(':id', $id);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':data2', $data);
$stmt->execute();
if ($stmt->rowCount()) {
return TRUE;
} else {
return FALSE;
}
}
public function destroySession($id) {
echo $id;
$q = "DELETE FROM `sessions` WHERE `id`= :id";
$stmt = $this->pdo -> prepare($q);
$stmt->execute(array(':id' => $id));
// Attempt execution
if ($stmt === true) {
echo " worked ";
return TRUE;
} else {
echo " no ";
return FALSE;
}
}
public function gcSession($maxTime) {
$q="DELETE FROM sessions WHERE (NOW()-startTime > $maxTime)";
$stmt = $this->pdo -> prepare($q);
if ($stmt->execute()) {
return TRUE;
} else {
return FALSE;
}
}
}
The function is being called this way:
// Store the user in the session and redirect:
$startSessions = new Sessions($pdo);
$_SESSION['data'] = 'IDnotOK';
$startSessions -> writeSession(session_id(), 'IDallOK');
$startSessions -> gcSession(1800);
The 'IDnotOK' is being sent to the database (sort of - it's 'data|s:7:"IDnotOK";'), instead of 'IDallOK'. If the $_SESSION['data'] isn't there, nothing is sent at all. The id is passed just fine. The timestamp also updates just fine. When I call:
$startSessions -> destroySession(session_id());
it doesn't matter how I try to pass the id, it will echo from within the function, but won't do anything to the database entry. Garbage collections works (probably because it only relies on the time and doesn't care about the id).
I wish I could list everything I've tried, but I've lost track. If there are any other questions that will help track down the problem, please ask. Thank You!
I am trying to fetch the data from database with compare of some fields using get_where but every time it's returning data even where condition does not satisfied...
My Code is:
function check_sec_token()
{
$sec_token=$this->session->userdata('sec_token');
$email_id=$this->session->userdata('email_id');
$query=$this->db->get_where($this->_registration,array('sec_token'=>$sec_token,'email_id'=>$email_id));
$rows=$query->num_rows();
return $query->result();
if($rows<1)
{
return false;
}
else
{
return true;
}
}
if $sec_token and $email_id is null then it returns all rows from the database..i also tried
function check_sec_token()
{
$sec_token=$this->session->userdata('sec_token');
$email_id=$this->session->userdata('email_id');
$query=$this->db->get_where($this->_registration,array('sec_token'=>$sec_token,'email_id'=>$email_id));
$rows=$query->num_rows();
return $this->db->last_query();
if($rows<1)
{
return false;
}
else
{
return true;
}
}
it's showing query
Select * from user_reg where sec_token=0 and email_id=0
Try this:
...
if ($sec_token == NULL && $email_id == NULL)
{
$query=$this->db->get($this->_registration);
}
else
{
$query=$this->db->get_where($this->_registration,array('sec_token'=>$sec_token,'email_id'=>$email_id));
}
...
Notice:
return $query->result();
This piece of code stops running the rest of your code! and your condition on row count is not considered!
you can do this instead:
$query=$this->db->get_where($this->_registration,array('sec_token'=>$sec_token,'email_id'=>$email_id));
$rows=$query->num_rows();
if($rows<1)
{
return false;
}
else
{
return $query->result();
}
Here if $sec_token and $email_id are null or "0" then query you will fetch all records.It will give all rows because when "where condition not satisfied then it fetch all records" try it.Also check your session is start or not and your values is set or not in it properly.
I don't know why this don't work at all. I maybe wrong with my understanding that is why.
here is the situation.
MVC pattern
form validation stuffs
Here are the codes
public function userExist($data)
{
$string = "SELECT student_number FROM users WHERE student_number = :user";
$sth = $this->db->prepare($string);
$sth->execute(array(
':user' => $data['user']
));
return $sth->rowCount() == 0 ? true : false;
}
public function validate($data) {
$this->userExist($data);
}
What i want is to return a string, that says "user exists", if the userExist method is false ... But this code doesn't work:
if($sth->rowCount() == 0) {
return true;
} else {
return "User Already Exists";
}
This is, how i call them in the controller:
if ($this->model->validate($data) == true) {
$this->model->create($data);
header('Location: '.URL.'users');
} else {
echo $this->model->validate($data);
die();
}
What do you think is the best solution?
First of all, you need to return the value of validate:
public function validate($data) {
$this->userExist($data);
}
But there are some other problems here. You don't need to call $this->model->validate($data) twice in your controller. You could do something like:
$result = false;
$result = $this->model->validate($data);
if ( true === $result {
$this->model->create($data);
header('Location: '.URL.'users');
} else {
die($result);
}
I have faced a problem .I want to select all rows by executing this function:
public function executeQuery($query,$fetch_mode=null) {
$rs = null;
if ($stmt = $this->getConnection()->prepare($query)) {
if ($this->executePreparedStatement($stmt, $rs,$fetch_mode)) {
return $rs;
}
} else {
throw new DBError($this->getConnection()->errorInfo());
}
}
private function executePreparedStatement($stmt, & $row = null,$fetch_mode=null) {
$boReturn = false;
if($fetch_mode==null) $fetch_mode=$this->fetch_mode;
if ($stmt->execute()) {
if ($row = $stmt->fetch($fetch_mode)) {
$boReturn = true;
} else {
$boReturn = false;
}
} else {
$boReturn = false;
}
return $boReturn;
}
But when I call it from my index page:
$objDB=new DB();
$objDB->connect();
// executeQuery returns an array
$result=$objDB->executeQuery("SELECT * FROM admin");
var_dump($result);
Only a single row is retrieved instead of all rows.
I also set mode using:
$result=$objDB->executeQuery("SELECT * FROM admin",PDO::FETCH_ASSOC);
But it still does not work.
The fetch method returns only the current row and sets the row pointer to the next row. To read all data in a PHP array you can use fetchAll().
Additionally return-by-reference is no good idea in PHP as it messes with PHP's copy-on-write mechanism and often creates trouble.
So I'd write oyure code something like this:
public function executeQuery($query,$fetch_mode=null) {
if ($stmt = $this->getConnection()->prepare($query)) {
$ret = $this->executePreparedStatement($stmt, $fetch_mode);
return $ret;
}
throw new DBError($this->getConnection()->errorInfo());
}
private function executePreparedStatement($stmt, $fetch_mode=null) {
if($fetch_mode==null) $fetch_mode=$this->fetch_mode;
if ($stmt->execute()) {
if ($rows = $stmt->fetchAll($fetch_mode)) {
return $rows;
}
}
return false;
}