Working on my first OOP app and I am having some trouble accessing the values of an array returned by a public function within my class. Here is the function -
//Process new transaction
public function addTransaction($amount, $payee, $category, $date, $notes) {
global $db;
//Check to see if payee exists in Payee table
$checkPayee = $db->prepare("SELECT * FROM payees WHERE name = ?");
$checkPayee->execute(array($payee));
$checkPayeeNum = $checkPayee->fetchColumn();
$payeeDetails = $checkPayee->fetch();
if ($checkPayeeNum < 1) {
$insertPayee = $db->prepare("INSERT INTO payees (name, cat) VALUES(?, ?)");
$insertPayee->execute(array($payee, $cat));
} else {
if ($payeeDetails['cat'] == "") {
$updatePayee = $db->prepare("UPDATE payees SET cat=? WHERE name=?");
$updatePayee->execute(array($cat, $payee));
}
}
//Process the transaction
$proc = $db->prepare("INSERT INTO transactions (amount, payee, cat, date, notes) VALUES (?, ?, ?, ?, ?)");
$proc->execute(array($amount, $payee, $cat, $date, $notes));
//Prepare array for JSON output
$todaysTrans = $this->fetchDailyTotal();
$weeklyTotal = $this->fetchWeeklyTotal();
$accountBalance = $this->balanceAccount();
$jsonOutput = array("dailyTotal" => $todaysTrans, "weeklyTotal" => $weeklyTotal, "accountBalance" => $accountBalance);
return $jsonOutput;
}
Instantiating the object is not the issue, trying to figure out how to access the $jsonOutput array. How would one accomplish this?
Thanks!
// In some other PHP file...
include 'YourClass.php';
$yourObject = new YourClass();
$returnedArray = $yourObject->addTransaction(...);
// Access the returned array values
echo 'Daily Total: ', $returnedArray['dailyTotal'], "\n";
echo 'Weekly Total: ', $returnedArray['weeklyTotal'], "\n";
echo 'Account Balance: ', $returnedArray['accountBalance'], "\n";
Also, for what it's worth, it's very confusing for you to be returning a PHP array called $jsonOutput, as it's not JSON encoded, which is what most developers will expect it to be. If you're wanting it to be JSON encoded, use json_encode() (see here for more info).
Related
I have found similar questions on here, but nothing quite right for my situation. I need to make multiple entries to a database from a combination of values from a set of arrays and repeated strings. To give an example:
$sql = "INSERT INTO sonch_MAIN.Concert (venue_id, date, ensemble_id, info, title, repertoire, time)
VALUES ('$venue', '$date', '1', '$info', '$title', '$repertoire_formatted', $time)";
$venue, $time, AND $date are arrays.
'1' should be added to EACH entry to the database without change.
$info, $title, AND $repertoire_formatted are strings that should be repeated, i.e., inserted without any variation, for each entry to the database.
So the following example shows what the contents of each variable might be:
$venue = array('venue1', 'venue7', 'venue50');
$date = array('2019-01-01', '2019-02-02', '2019-03-03');
$time = array('20:00:00', '19:00:00', '18:00:00');
$info = 'General info about this event';
$repertoire_formatted = 'Music that people will play at this event';
My SQL database is set up to take the different types of data for each input variable.
HERE is the code I have (not working):
session_start();
$_SESSION["servername"] = "localhost";
$_SESSION["username"] = "sonch_nB";
$_SESSION["password"] = 'hello';
$_SESSION["dbname"] = "sonch_MAIN";
date_default_timezone_set('Europe/Zurich');
$venue = ($_POST['venue']);
$date = ($_POST['date']);
$ensemble_id = '1'; //THIS WILL BE SET VIA LOGIN
$info = ($_POST['info']);
$title = ($_POST['title']);
//FORMAT INCOMING VARS CODE SKIPPED//
// Create connection
$conn = new mysqli($_SESSION['servername'], $_SESSION['username'], $_SESSION['password'], $_SESSION['dbname']);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
//NEED TO LOOP INPUT TO MYSQL NUMBER OF VALUES IN ARRAY
$stmt = $conn->prepare("INSERT INTO sonch_MAIN.Concert (venue_id, date, ensemble_id, info, title, repertoire, time) VALUES (?, ?, '1', ?, ?, ?, ?)");
$stmt->bind_param("ssssss", $v, $d, $info, $title, $repertoire_formatted, $t);
for ($i = 0; $i < count($venue); $i++) {
$v = $venue[$i];
$d = $date[$i];
$t = $time[$i];
$stmt->execute();
}
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$stmt->close();
You should use a prepared statement. In MySQLi (assuming your connection is $conn):
$stmt = $conn->prepare("INSERT INTO sonch_MAIN.Concert (venue_id, date, ensemble_id, info, title, repertoire, time)
VALUES (?, ?, '1', ?, ?, ?, ?)");
$stmt->bind_param("ssssss", $v, $d, $info, $title, $repertoire_formatted, $t);
for ($i = 0; $i < count($venue); $i++) {
$v = $venue[$i];
$d = $date[$i];
$t = $time[$i];
if ($stmt->execute() === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $conn->error;
}
}
$stmt->close();
"i am trying to develop an script which allows me to insert multiple rows from an jsonarray in mysql database, but upon testing only one rows is being inserted and here is my code:
<?php
$con = mysqli_connect($host,$user,$password,$database) or die('Unable to Connect');
if($_SERVER["REQUEST_METHOD"]=="POST")
{
$jsonData=file_get_contents("sampledata.json");
$jsonString=json_decode($jsonData,true);
foreach($jsonString['Order Summary'] as $cart)
{
$name=$cart['ProductName'];
$price=$cart['ProductPrice'];
$quantity=$cart['ProductQuantity'];
$cost=$cart['ProductCost'];
$seller=$cart['SellerId'];
$stmt=$con->prepare("INSERT INTO sProducts(Name,Price,Quantity,Cost,Sellerid)VALUES(?,?,?,?,?)");
$stmt->bind_param("sssss",$name,$price,$quantity,$cost,$seller);
if($stmt->execute())
return json_encode("data inserted");
return json_encode("error");
}
}
can anyone tell me where is the mistake or could guide me into this direction ?
For one, you are reutrning in the first iteration of the loop - which means that the script stops. return should only be used to return from a function.
If you remove both returns, that will make the loop continue until its done.
And you should not prepare the query inside the loop, its not needed - and much more efficient to prepare it before you start looping (it can be used multiple times with different values when you bind and execute in a loop). I've also added some spaces in the code to make it easier to read
$con = mysqli_connect($host,$user,$password,$database) or die('Unable to Connect');
$msg = "data inserted";
if ($_SERVER["REQUEST_METHOD"]=="POST") {
$jsonData = file_get_contents("sampledata.json");
$jsonString = json_decode($jsonData,true);
$stmt = $con->prepare("INSERT INTO sProducts (Name, Price, Quantity, Cost, Sellerid) VALUES (?, ?, ?, ?, ?)");
foreach($jsonString['Order Summary'] as $cart) {
$name = $cart['ProductName'];
$price = $cart['ProductPrice'];
$quantity = $cart['ProductQuantity'];
$cost = $cart['ProductCost'];
$seller = $cart['SellerId'];
$stmt->bind_param("sssss", $name, $price, $quantity, $cost, $seller);
if (!$stmt->execute())
$msg = "Something went wrong";
}
}
return json_encode($msg);
i need somehow to check if field exist in db, and then if exist, just update price, if not, insert fields. I am using simplxml for parsing data to db from xml.
here is my code without if statement, just insert into two databese.
I need to check from db products if ident exist, so if not exist, do all that code down, if exist just update price in db products
foreach ($lib->product as $data) {
$manufacturer = (string) $data->manufacturer;
$ident = (string) $data->id;
$name = (string) $data->name;
$category = (string) $data->category;
$subcategory = (string) $data->subcategory;
$price = (int) ($data->price * 1.2 * 1.4 * 1.1);
$image = (string) $data->images->image[0];
$insert = $db->prepare('INSERT INTO products (ident, manufacturer,name,category,subcategory,price,image) VALUES (?, ?, ?, ?, ?, ?, ?)');
$insert->bind_param('sssssss', $ident, $manufacturer, $name, $category, $subcategory, $price, $image);
$insert->execute();
foreach($data->specifications->attribute_group as $group) {
$attribute_group = (string) $group->attributes()['name'];
foreach($group as $attr) {
$attribute = (string) $attr->attributes()['name'];
$value = (string) $attr->value;
$insert = $db->prepare('INSERT INTO spec (attr_group,attr_name, attr_value, product_id) VALUES (?, ?, ?, ?)');
$insert->bind_param('ssss', $attribute_group, $attribute, $value, $ident);
$insert->execute();
}
}
}
To do in one query, look up MySQL's ON DUPLICATE KEY UPDATE functionality for INSERT.
Then use $insert->rowCount() if you're using PDO or $insert->affected_rows for mysqli.
If the first insert tried to already insert a key that existed and updates a value, then rowCount()/affected_rows will be 2; if it just inserted a record then rowCount()/affected_rows will be 1. It will be 0 if the INSERT was unsuccessful.
e.g. for PDO:
switch($insert->rowCount()) {
case 2: // UPDATE occurred thanks to 'ON DUPLICATE UPDATE KEY'
// SOME CODE HERE IF YOU LIKE
break;
case 1: // INSERT occurred as no duplicate
// CODE TO INSERT INTO SECOND TABLE
break;
case 0:
default:
// NEITHER THE ABOVE OCCURRED SO CODE TO HANDLE ERROR
}
$query = "SELECT * name FROM yourtable";
$bool = true;
if($r = #mysql_query($query))
{
while($row = #mysql_fetch_array($r))
{
if( ($row['id'] == $id))
{
$bool = false;
break;
}
}
}
if($bool) {
UPDATE
}
else
{
INSERT
}
I am converting from mysqli to PDO and very much a beginner with this. Here is my update statement for my database 'users'
public function pdo_update_test() {
$sql = "UPDATE users SET visible_password = ?, hashed_password = ?, ";
$sql .="temp_hashed_password = ?, email = ?, first_name= ?, last_name = ?, ";
$sql .="position = ?, location = ?, city = ?, country = ?, institution = ? ";
$sql .="interests = ?, profile_comment = ? WHERE id =" . $this->id;
$query = $handler->prepare($sql);
$result = array($visible_password, $hashed_password, $temp_hashed_password, $email,
$first_name, $last_name, $position, $location, $city, $country, $institution,
$interests, $profile_comment);
$query->execute($result);
if (($query = $handler->prepare($sql)) === false) {
print_r($handler->errorInfo());
}
if ($query->execute($result) === false) {
print_r($query->errorInfo());
}
}
I am using ? rather than nameholders because once I have this working I am going to try to make it abstract so I can use it in all the classes in my site and I have found it easier with ? than nameholders. When I run the following it fails to work. I am sure an obvious error on my part but I can't seem to see the issue....
$user = new User();
$user->id= 256;
$visible_password = "Bob";
$user->pdo_update_test();
I have found a solution to make the whole thing dynamic. I won't presume that its going to be helpful for others (as I am the beginner) but i though I would post it anyway....
If you see problems or have criticisms please let me know
public function pdo_update_test(){
$attributes = $this->attributes();
$attribute_pairs = array();
foreach($attributes as $key => $value) {
if(isset($value))
$attribute_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE ".self::$table_name." SET ";
$sql .= join(", ", $attribute_pairs);
$sql .= " WHERE id=". $this->id;
$query = $handler->prepare($sql);
$query->execute(array());
}
What you need is to create SET statement for the query dynamically. To make it contain only actual fields you have values for.
So, for the code given, it should produce a query
UPDATE users SET visible_password = ? WHERE id = ?
-- but not one you wrote above with all the fields listed
and it is not PDO related problem - it's rather just basic string manipulation, every PHP user is supposed to be able to write. If you can't, you can refer to PDO tag wiki for the code to adopt.
To make it work your code have to be like this
$user = new User();
$user->id= 256;
$data = array('visible_password' => "Bob");
$user->pdo_update_test($data);
where pdo_update_test will create the above SQL query out of $data array
I'm having a problem importing .CSV data into a SQL database. I'm trying to use PDO in my PHP file to accomplish this and I can't seem to figure this out.
if (isset($_FILES['uploadedfile'])) {
// get the csv file and open it up
$file = $_FILES['uploadedfile']['tmp_name'];
$handle = fopen($file, "r");
try {
// prepare for insertion
$query_ip = $db->prepare('
INSERT INTO projects (
id, project_name, contact, pm, apm,
est_start, est_end, trips, tasks, perc_complete,
bcwp, actual, cpi, bcws, bac,
comments, status, project_revenue, profit_margin, pm_perc,
audited, account_id
) VALUES (
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?, ?
)');
$data = fgetcsv($handle,1000,",","'");
$query_ip->execute($data);
$count = $query_ip->rowCount();
fclose($handle);
} catch(PDOException $e) {
die($e->getMessage());
}
echo 'Projects imported ' . $count . ' rows were affected';
} else {
echo 'Could not import projects';
}
Now this works, kind of. It imports the data but as you may have guessed this is only inserting the first row of the .CSV file, which by the way is the column headers. So I need to skip the first row and loop through the rest of this .CSV file.
Obviously throwing me some code would solve this, but more than that I would like an explanation of how to do this properly with PHP Data Objects (PDO). All the examples I've come across either have huge flaws or don't use PDO. Any and all help is welcomed and appreciated.
The comments helped me come up with this answer. I used the following code
if (isset($_FILES['uploadedfile'])) {
// get the csv file and open it up
$file = $_FILES['uploadedfile']['tmp_name'];
$handle = fopen($file, "r");
try {
// prepare for insertion
$query_ip = $db->prepare('
INSERT INTO projects (
id, project_name, contact, pm, apm,
est_start, est_end, trips, tasks, perc_complete,
bcwp, actual, cpi, bcws, bac,
comments, status, project_revenue, profit_margin, pm_perc,
audited
) VALUES (
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?, ?, ?, ?, ?,
?
)
');
// unset the first line like this
fgets($handle);
// created loop here
while (($data = fgetcsv($handle, 1000, ',')) !== FALSE) {
$query_ip->execute($data);
}
fclose($handle);
} catch(PDOException $e) {
die($e->getMessage());
}
echo 'Projects imported';
} else {
echo 'Could not import projects';
}
I hope this helps future readers properly import their .CSV files using PDO. It should be noted this should not be used on a live server/site. This code has 0 protection against potentially harmful uploads.
error_reporting(E_ALL);
ini_set('display_errors', 1);
/* Database connections */
$_host = 'localhost';
$_name = 'root';
$_password = 'root';
$_database = 'TEST';
/* ========= Variables =========== */
/**
* Defines the name of the table where data is to be inserted
*/
$table = 'terms';
/**
* Defines the name of the csv file which contains the data
*/
$file = 'terms.csv';
/* =========== PDO ================= */
try {
$link = new PDO('mysql:dbname=' . $_database . ';host=' . $_host . ';charset=utf8', $_name, $_password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$link->exec("set names utf8");
} catch (PDOException $ex) {
die(json_encode(array('outcome' => false, 'message' => 'Unable to connect')));
}
$link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
/* ========= Load file content in an array ========== */
$rows = array_map('str_getcsv', file($file));
$header = array_shift($rows);
$csv = array();
foreach ($rows as $row) {
$csv[] = array_combine($header, $row);
}
/* ========= Insert Script ========== */
foreach ($csv as $i => $row) {
insert($row, $table);
}
function insert($row, $table) {
global $link;
$sqlStr = "INSERT INTO $table SET ";
$data = array();
foreach ($row as $key => $value) {
$sqlStr .= $key . ' = :' . $key . ', ';
$data[':' . $key] = $value;
}
$sql = rtrim($sqlStr, ', ');
$query = $link->prepare($sql);
$query->execute($data);
}
echo "Done inserting data in $table table";