Learning PHP and creating associative arrays.
Trying to create associative array that describes an activity. An activity for this example is 354 and 355.
This is my current code:
$query = $db->prepare('SELECT item_id FROM kh_program_item_info WHERE '. $where);
$query->execute();
if($query->rowCount() > 0){
while($john = $query->fetch(PDO::FETCH_OBJ)){
$key1 = $john->item_id;
$report-> $key1= array();
}
foreach ($report as $key=>$johnval) {
$where = 'item_id = ' . $key;
$query = $db->prepare('SELECT activity_desc, DATE_FORMAT(activity_date,"%d/%m/%Y") AS activityDate FROM kh_program_items WHERE '. $where);
$query->execute();
$results = $query->fetch(PDO::FETCH_OBJ);
$report->$key = $results;
echo '<pre>';
echo print_r($report);
echo '</pre>';
}
} else {
echo '<p>there are no activities</p>';
}
this will yield results.
stdClass Object
(
[354] => stdClass Object
(
[activity_desc] => <p>Send Activity</p>
[activityDate] => 08/11/2016
)
[355] => stdClass Object
(
[activity_desc] => <p>Send Activity 2</p>
[activityDate] => 11/11/2016
)
)
I am now trying to add more information for 354 and 355.
I have revisited the code and here is new code:
$query = $db->prepare('SELECT item_id FROM kh_program_item_info WHERE '. $where);
$query->execute();
if($query->rowCount() > 0){
while($john = $query->fetch(PDO::FETCH_OBJ)){
$key1 = $john->item_id;
$report-> $key1= array();
}
foreach ($report as $key=>$johnval) {
$where = 'item_id = ' . $key;
$query = $db->prepare('SELECT activity_desc, DATE_FORMAT(activity_date,"%d/%m/%Y") AS activityDate FROM kh_program_items WHERE '. $where);
$query->execute();
$results = $query->fetch(PDO::FETCH_OBJ);
$report->$key = $results;
$query = $db->prepare('SELECT info_value FROM kh_program_item_info WHERE '. $where .' AND info_type="program_category"');
$query->execute();
$info_value = $query->fetch(PDO::FETCH_OBJ);
$where = 'category_id = ' . $info_value->info_value;
$query = $db->prepare('SELECT category_name FROM kh_program_categories WHERE '. $where);
$query->execute();
$actcategories = $query->fetch(PDO::FETCH_OBJ);
$report->$key = $actcategories;
echo '<pre>';
echo print_r($report);
echo '</pre>';
}
} else {
echo '<p>there are no activities</p>';
}
this will obviously overwrite what I have created and yield the following results:
stdClass Object
(
[354] => stdClass Object
(
[category_name] => Parent Input
)
[355] => stdClass Object
(
[category_name] => Children's Menu
)
)
The problem is $myactivity->$key = $actcategories;.
How do I append to the end without overwriting information?
I need to yield this result
stdClass Object
(
[354] => stdClass Object
(
[activity_desc] => <p>Send Activity</p>
[activityDate] => 08/11/2016
[category_name] => Parent Input
)
[355] => stdClass Object
(
[activity_desc] => <p>Send Activity 2</p>
[activityDate] => 11/11/2016
[category_name] => Children's Menu
)
)
Thanks in advance.
You'll need to build your array first and then, send it to the object.
i.e. :
foreach ($report as $key=>$johnval) {
$where = 'item_id = ' . $key;
$query = $db->prepare('SELECT activity_desc, DATE_FORMAT(activity_date,"%d/%m/%Y") AS activityDate FROM kh_program_items WHERE '. $where);
$query->execute();
// build first array
$result_first_query = $query->fetch(PDO::FETCH_OBJ);
$query = $db->prepare('SELECT info_value FROM kh_program_item_info WHERE '. $where .' AND info_type="program_category"');
$query->execute();
$info_value = $query->fetch(PDO::FETCH_OBJ);
$where = 'category_id = ' . $info_value->info_value;
$query = $db->prepare('SELECT category_name FROM kh_program_categories WHERE '. $where);
$query->execute();
// build second array
$result_second_query = $query->fetch(PDO::FETCH_OBJ);
// put them together in $report->$key
$report->$key = $result_first_query + $result_second_query;
echo '<pre>';
print_r($report);
echo '</pre>';
}
Hope it helps.
I did manage to push after i used fetch_assoc.
I guess it was just format it didnt like but thank you.
Related
I can't get SQLite LIKE search to work with PDO. This works fine with
MySQL and MariaDB but I can't get this to work with SQLite3.
I have also tried with different examples from internet.
I'm using sqlite3 version 3.35.3 and version PHP 8.0.3 on Linux 5.9.
echo '<pre>';
$createTable = <<<EOT
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
INSERT INTO users(name) VALUES
('alpha'),
('beta'),
('gamma'),
('theta');
EOT;
if (!file_exists(__DIR__ . '/test.db'))
{
echo "#CREATING DB# <br>";
$pdo = new \PDO('sqlite:' . __DIR__ . '/test.db');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->exec($createTable);
$term = 'et';
$sql = " SELECT * FROM users WHERE name LIKE :term ";
$stmt = $pdo->prepare($sql);
$prepare = [
'term' => "'%". $term ."%'"
];
echo getPdoCompiledSqlString($sql, $prepare) . '<br>';
if($stmt)
{
$stmt->execute($prepare);
//$stmt->debugDumpParams();
debugPdo($stmt);
echo "#FETCHALL# <br>";
print_r( $stmt->fetchAll() );
}
}
else
{
echo "#DELETING DB#";
unlink(__DIR__ . '/test.db');
}
function getPdoCompiledSqlString($sql, $params){
echo "#SQL STRING# <br>";
$keys = [];
foreach ($params as $key => $value){ if (is_string($key)) {$keys[] = '/:'.$key.'/';} else {$keys[] = '/[?]/';}}
return preg_replace($keys, $params, $sql, 1, $count);
}
function debugPdo(&$stmt){
echo "#DEBUG PDO OBJ# <br>";
$stmt->debugDumpParams();
}
echo '<pre>';
You don't need to quote the parameter :
'term' => "%". $term ."%"
Instead of
'term' => "'%". $term ."%'"
Because the parameter will automatically be quoted during execute()
$term = 'et';
$sql = " SELECT * FROM users WHERE name LIKE :term ";
$stmt = $pdo->prepare($sql);
$prepare = [
'term' => "%". $term ."%" //only the search string: `%et%`
];
$stmt->execute($prepare);
print_r($stmt->fetchAll());
Output:
Array
(
[0] => Array
(
[id] => 2
[0] => 2
[name] => beta
[1] => beta
)
[1] => Array
(
[id] => 4
[0] => 4
[name] => theta
[1] => theta
)
)
I am using SQLite3 and PHP, and try to write a generic function to execute my queries.
For this I would like to retrieve the name of the parameters from variables in the bindParam.
But it doesn't seem to work. Here is a code showing the unexpected behavior:
<?php
header("Content-Type: text/plain");
$db = new SQLite3(':memory:');
$db->exec("create table mytable (lsid integer primary key autoincrement, usid TEXT, source TEXT)");
$myid = 'agoodid';
$mydatasources = array('home', 'news');
foreach($mydatasources as $datasource) {
$params[] = array(':datasource' => $datasource, ':usid' => $myid);
}
echo "here are the inputs : " .PHP_EOL;
print_r($params);
$querystring = 'insert into mytable (source, usid) values (:datasource, :usid)' ;
echo " I prepare the query '$querystring'" . PHP_EOL;
$query = $db->prepare($querystring);
foreach($params as $set) {
foreach($set as $key => $value) {
echo " Setting $key = $value." . PHP_EOL;
$query->bindParam($key, $value, SQLITE3_TEXT);
}
echo " I execute the query" . PHP_EOL;
$queryres[] = $query->execute();
$query->reset();
}
$results = $db->query('select * from mytable');
echo "and here is what I get : " . PHP_EOL;
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
print_r($row);
}
?>
And here is the final result :
Array
(
[lsid] => 1
[usid] => agoodid
[source] => agoodid
)
Array
(
[lsid] => 2
[usid] => agoodid
[source] => agoodid
)
All the parameters seem to be bound with the value of the last bound parameter.
The expected result is:
Array
(
[lsid] => 1
[usid] => agoodid
[source] => home
)
Array
(
[lsid] => 2
[usid] => agoodid
[source] => news
)
How to do this? As a reminder: the aim is to not hard code the name of the parameter in bindParam.
I got the binParam function wholy wrong. it is attaching to the given parameter in the sql query a reference to the given variable in php.
I have to use bindValue instead.
Whenever I run this code through the SalesForce PHP api, it fails with err:Notice: Trying to get property of non-object
$query ="SELECT accountId,Status,Id,Service_Account_DMKT__r.name,(select Activity_Type__c from Tasks) from case where Owner.Name ='" . $name . "' AND CreatedDate = THIS_MONTH AND Record_type_name__c='Performance Reviews' AND status NOT IN ('')";
$response = $mySforceConnection->query($query);
$queryResult = new QueryResult($response);
foreach($queryResult->records as $case){
//for ($queryResult->rewind(); $queryResult->pointer < $queryResult->size; $queryResult->next()) {
$callCounter = 0;
$emailCounter = 0;
$accountId = $case->current()->accountId;
$accountName=$case->current()->Service_Account_DMKT__r->Name;
$caseId= $case->current()->Id;
if($case->any['Tasks']->records) {
$counter=0;
foreach($case->any['Tasks']->records as $record) {
$taskRecord = $record->any;
if (strpos($taskRecord, 'Call - Outbound') !== false) {
$callCounter++;
} else {
$emailCounter++;
}
$counter++;
}
}
echo '<p>AccountName=' . $accountName . '</p><p>CaseId=' . $caseId . '</p>';
echo '<p>' . $callCounter . ' Calls and ' . $emailCounter . ' emails';
echo'<hr>';
$index++;
}
print_r($case);
I know it is because of these three lines. I'm not stepping through the object correctly.
$accountId = $case->current()->accountId;
$accountName=$case->current()->Service_Account_DMKT__r->Name;
$caseId= $case->current()->Id;
But I'm not sure what to use instead of current(). Below is the response object from the SF API
stdClass Object
(
[type] => Case
[Id] => Array
(
[0] => 5000e00001J7L0pAAF
[1] => 5000e00001J7L0pAAF
)
[any] => Array
(
[0] => 00130000002bqXiAAIClosed - Contact Declined5000e00001J7L0pAAF
[Service_Account_DMKT__r] => stdClass Object
(
[type] => Account
[Id] =>
[any] => brinsoncorsicanafordfd
)
[Tasks] => stdClass Object
(
[done] => 1
[queryLocator] =>
[records] => Array
(
[0] => stdClass Object
(
[type] => Task
[Id] =>
[any] =>
)
)
[size] => 1
)
)
)
I finally managed to fix it by converting the response back to another object
$query ="SELECT accountid,Status,Id,Service_Account_DMKT__r.name,(select Activity_Type__c,subject from Tasks) from case where Owner.Name ='" . $SFName . "' AND CreatedDate = THIS_MONTH AND Record_type_name__c='Performance Reviews' AND status NOT IN ('')";
$response = $mySforceConnection->query($query);
$queryResult = new QueryResult($response);
foreach($queryResult->records as $case){ //For every record within $queryResult
$callCounter = 0; //Set up our task counters
$emailCounter = 0;
$sObject = new SObject($case); //turn $case back into a SObj to easy step thru
$accountId= $sObject->AccountId; //Pull AccountId from $sObject
$accountName=$sObject->Service_Account_DMKT__r->Name;
$caseId=$sObject->Id;
$caseStatus=$sObject->Status;
if(!isset($sObject->queryResult)) { //Check if there are any tasks on the record, otherwise we'll get an error
$callCounter=0; //if there are no tasks, set counters to 0
$emailCounter=0;
}else{
$counter=0;
foreach($case->any['Tasks']->records as $record) { //for each task in the $case
$taskObject = new SObject($record); //Turn $record into taskObject so we can step through it.
$taskType = $taskObject->Activity_Type__c; //Pull the activity type out of TaskObject
if($taskType == "Call - Outbound"){ //Calling $taskType actually allows us to compare the obj to a string, where as going through this in an array format would not!
$callCounter++; //increase counter if the taskType is a call
} else {
$emailCounter++;
}
}
}
echo '<p>AccountName=' . $accountName . '</p><p>AccountID=' . $accountId . '</p><p>CaseId=' . $caseId . '</p><p>CaseStatus=' . $caseStatus . '</p>';
echo '<p>' . $callCounter . ' Calls and ' . $emailCounter . ' emails';
echo'<hr>';
}
I'm trying to write my own little blog.
For this, I use the CodeIgniter framework.
In my blog posts, I also want to save a category and some keywords.
I need to be able to check if a category/keyword already exists, if not a new one needs to be created.
The ID of the existing/new one is saved to be used in a 'connecting' table.
I have the following database setup.
posts - id (AI), title, date, content
categories - id (AI), category
post_categories - post, category
keywords - id (AI), keyword
post_keywords - post, keyword
*AI = Auto Increment
The tables posts, post_categories and post_keywords get updated, the tables categories and keywords remain empty. The category and keyword values in the connecting tables are ofc incorrect.
When troubleshooting my code, I echo'ed every variable in every step.
For some reason, the whole if/else structures checking whether a category or keyword already exists is skipped.
/**
* Insert post into database
* Check if category already exists, if not add it
* Check if keywords already exist, if not add them
* Insert post-category and post-keyword links
* #param array $data
* #return boolean success
*/
function create($data) {
print_r($data);
try {
// posts
$this->db->insert('posts', array(
'title' => $data['title'],
'date' => $data['date'],
'content' => $data['content']
));
$postId = $this->db->insert_id();
echo '<p>Inserted new post (' . $data['title'] . ') at ' . $postId . '</p>';
// category
$category = $data['category'];
$query = $this->db->get_where('categories', array('category' => $category));
$cat = 666;
if ($this->db->count_all_results() == 1) {
foreach ($query->result() as $row) {
$cat = $row->id;
echo '<p>cat = ' . $cat . '</p>';
}
} else {
$this->db->insert('categories', array(
'category' => $category
));
$cat = $this->db->insert_id();
echo '<p>cat = ' . $cat . '</p>';
}
echo '<p>Inserted new category (' . $category . ') at ' . $cat . '</p>';
if($cat == 666) { echo ':('; }
$this->db->insert('post_categories', array(
'post' => $postId,
'category' => $cat
));
// keywords
$keywords = $data['keywords'];
foreach ($keywords as $keyword) {
$query = $this->db->get_where('keywords', array('keyword' => $keyword));
$key = 666;
if ($this->db->count_all_results() == 1) {
foreach ($query->result() as $row) {
$key = $row->id;
echo '<p>key = ' . $key . '</p>';
}
} else {
$this->db->insert('keywords', array(
'keyword' => $keyword
));
$key = $this->db->insert_id();
echo '<p>key = ' . $key . '</p>';
}
echo '<p>Inserted new keyword (' . $keyword . ') at ' . $cat . '</p>';
if($key == 666) { echo ':('; }
$this->db->insert('post_keywords', array(
'post' => $postId,
'keyword' => $key
));
}
return true;
} catch (Exception $e) {
print '<p>ERROR:</p>' . $e;
return false;
}
}
Also in my controller
echo '<p>' . ($this->m_posts->create($post) ? 'no errors :)' : 'error! :(') . '</p>';
Result
Array ( [title] => Foo Bar [date] => 2014-05-22 [content] => lorum ipsum dolore si amet [category] => Category [keywords] => Array ( [0] => Some [1] => Keywords ) )
Inserted new post (Foo Bar) at 2
Inserted new category (Category) at 666
:(
Inserted new keyword (Some) at 666
:(
Inserted new keyword (Keywords) at 666
:(
no errors :)
In my database
POSTS
stdClass Object ( [id] => 1 [title] => Title [date] => 2014-05-22 [content] => okokokokokokok )
stdClass Object ( [id] => 2 [title] => Foo Bar [date] => 2014-05-22 [content] => lorum ipsum dolore si amet )
CATEGORIES
POST_CATEGORIES
stdClass Object ( [post] => 1 [category] => 666 )
stdClass Object ( [post] => 2 [category] => 666 )
KEYWORDS
POST_KEYWORDS
stdClass Object ( [post] => 1 [keyword] => 666 )
stdClass Object ( [post] => 2 [keyword] => 666 )
stdClass Object ( [post] => 2 [keyword] => 666 )
note: I use 99 as a temp value to test if the variable was filled because I first thought the variable's value didn't leave the scope of the if/else. But echo'ing the values of the vars inside the if/else prints nothing. It seems to skip the whole if/else sections.
Adjust the code to:
In if statement num_rows of query it self
If you expect 1 record do a $query->row() directly instead of a foreach loop.
$query = $this->db->get_where('categories', array('category' => $category));
$cat = 666;
if ($query->num_rows() == 1) {
$row = $query->row();
$cat = $row->id;
echo '<p>cat = ' . $cat . '</p>';
} else {
$this->db->insert('categories', array(
'category' => $category
));
$cat = $this->db->insert_id();
echo '<p>cat = ' . $cat . '</p>';
}
After hours going around in circles I gave up and ask for help.
I have an array which looks like:
[field01] => Array
(
[name] => test01
[prefix] => C01
)
[field02] => Array
(
[url] => http://www.url.com
[user] => a_user
[password] => a_password
)
[filed03] => Array
(
[0] => Array
(
[id] => 1
[Type] => standard
[Name] => name
)
[1] => Array
(
[id] => 5
[Type] => standard
[Name] => name
)
)
Now I want to go through that array and get the following output as a return from a recursive function:
Array (
[0] = "The values of field01: name, prefix - test01, C01"
[1] = "The values of field02: url, user, password - http://www.url.com, a_user, a_password"
[2] = "The values of field03: id, Type, Name - 1, standard, name"
[3] = "The values of field03: id, Type, Name - 5, standard, name"
)
I have tried it with a recursive function but stuck with field03 to save the name.
Any help for that?
UPDTAE:
here is the array, so you don't have to write it:
$data['field01']['name'] = "field01";
$data['field01']['prefix'] = "C01";
$data['field02']['url'] = "http://www.url.com";
$data['field02']['user'] = "a_user";
$data['field02']['password'] = "a_password";
$data['field03'][0]['List_id'] = 1;
$data['field03'][0]['Type'] = "standard";
$data['field03'][0]['Name'] = "name";
$data['field03'][1]['List_id'] = 5;
$data['field03'][1]['Type'] = "standard";
$data['field03'][1]['Name'] = "name";
Thanks in advance!
<?php
$data['field01']['name'] = "field01";
$data['field01']['prefix'] = "C01";
$data['field02']['url'] = "http://www.url.com";
$data['field02']['user'] = "a_user";
$data['field02']['password'] = "a_password";
$data['field03'][0]['List_id'] = 1;
$data['field03'][0]['Type'] = "standard";
$data['field03'][0]['Name'] = "name";
$data['field03'][1]['List_id'] = 5;
$data['field03'][1]['Type'] = "standard";
$data['field03'][1]['Name'] = "name";
$text = '';
foreach ($data as $k => $fields) {
if (isset($fields[0])) {
foreach ($fields as $field) {
$text .= 'The values of ' . $k . ': ' . traverse($field) . "\n";
}
} else {
$text .= 'The values of ' . $k . ': ' . traverse($fields) . "\n";
}
}
echo $text;
function traverse($fields) {
$keys = array_keys($fields);
$values = array_values($fields);
return implode(', ', $keys) . ' - ' . implode(', ', $values);
}
?>
This assumes if there is an array of arrays, it is all arrays. In other words, you aren't mixing strings with arrays.
$resultArray = array();
function process($inputArray, $fieldName) {
$result = array();
$keys = array_keys($inputArray);
if (!is_array($inputArray[0])) {
$result[] = "The value of $fieldName: ".implode($keys,', '). ' - '. implode($inputArray, ', ');
} else {
foreach($inputArray as $arr) {
$result = array_merge($result, process($arr, $fieldName));
}
}
return $result;
}
foreach($data as $k=>$v) {
$processed = process($v, $k);
$resultArray = array_merge($resultArray, $processed);
}
print_r($resultArray);