I have a problem. I have a website with people and different transactions they make to and from a fake online bank. I want to be able to store an array of each person's transactions on my mysql database. I want each transaction to be defined as an associative array with a timestamp and the sql query that represents their transaction with the "bank".
Then I want those, after being serialized, to be the values of a transactions array that holds all of their transactions. Then I want to serialize that and store it in the database so that later I can add a transaction by unserializing it and appending a serialized array of another transaction to it. So far this code below works except that it just overwrites the one transaction and doesn't append a new one. I'd really appreciate any help.
Thanks in advance
function modify_transactions($row, $sql)
{
$sql=mysql_real_escape_string($sql);
if(isset($row["TRANSACTIONS"]))
{
$transactions = unserialize($row["TRANSACTIONS"]);
}
else
{
$transactions = array();
}
$transaction_array = array("timestamp"=>time(),"query"=>$sql);
$transaction_data = serialize($transaction_array);
$transactions[] = $transaction_data;
$transactions_upload = serialize($transactions);
$name = $row["NAME"];
$query = "UPDATE band.students SET TRANSACTIONS = '$transactions_upload' WHERE students.NAME = '$name'";
mysql_query($query);
}
If I were you, I'd rather go for a new table where every entry would represent a transaction and that had a foreign key student_id.
That'd be much, much, much cleaner and more flexible and scalable (i.e. what if you want to show the last 3 transactions of user X? What if a user had several million transactions?).
First, you don't need to serialize each array, then serialize again. Serialize is recursive:
$array = array(
array(
'1',
array()
),
array(
'2',
array()
)
);
$serialized = serialize($array);
$unserialized = unserialize($serialized);
echo "<pre>";
print_r($unserialized);
echo "</pre>";
Prints:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
)
)
)
So just serialize right before inserting into the database.
Second, you should change your database structure. Like vzwick mentioned, create a new table with a foreign key of the student. That way each entry represents a transaction.
Also, why are you storing the actual SQL query? That doesn't make any sense to me. Why don't you actually make a fake transaction?
Related
I started getting into arrays and don't quite get it to work well. I'm used to work with explode/implode functions but I though arrays would make my life easier in this part of the code. Here is the function called:
function save_event($event_items = NULL) {
include 'connect.php';
$now = date("Y-m-d H:i:s");
$sqla = "
INSERT INTO `event`(`event_items`, `event_entered`)
VALUES ('$event_items','$now')";
$resulta = mysqli_query($link, $sqla);
if(!$resulta)
{
echo '<br/>An error occurred while inserting your data. Please try again later.<br/>';
}
else
{ echo 'this is the variable to be stored:<br/>';
print_r($event_items);
$sql = "SELECT * FROM `event` WHERE event_entered = '".$now."'";
$result = mysqli_query($link, $sql);
if($result)
{ while($row = mysqli_fetch_assoc($result))
{ echo '<br/></br>This is the value of the database:<br/>';
print_r ($row['event_items']);
}
}
}
}
This function prints:
this is the variable to be stored:
Array( [0] => Array ( [item] => Powered Speaker [note] => [quantity] => 2 [price] => 200.00 [category] => Audio ) [1] => Array ( [item] => Wireless Microphone [note] => Lavalier [quantity] => 3 [price] => 175.00 [category] => Audio ))
This is the value of the database:
Array
In phpMyAdmin, all I see in the column event_items is the word Array.
Additional info:
I have a table called Groups, each group will have one or multiple orders (another table called Order) and each order will have also one or multiple events (another table). Lastly, each event will have one or multiple items (each item with its corresponding price, quantity, note and category), which are stored in one (or many) columns in the Event table.
Don't try to store an array in one field. You should store each item in the array as it's own row in a related table.
You are trying to insert multiple values in a single database record, this is not impossible but it's also not recommended in general.
The main reason someone would do this would be for optimization, which is not at all something you should worry about for now.
What you really want to do is review your database schema, if you wish to store an array of value, you need to create a new row (record) for each of those. This might necessitate the creation of another table, depending on what you want to do.
You could serialize your array with the serialize() function.
Example:
serialize($event_items);
Generates a storable representation of a value.
This is useful for storing or passing PHP values around without losing
their type and structure.
http://php.net/manual/en/function.serialize.php
I have a large set of data stored in a multi-dimensional array. An example structure is as below:
Array
(
[1] => Array
(
[0] => motomummy.com
[1] => 1921
[2] => 473
)
[4] => Array
(
[0] => kneedraggers.com
[1] => 3051
[2] => 5067
)
)
I also have a table in a mysql database that currently contains ~80K domain names. This list will grow monthly by possibly ~10K+ domain names. The goal is to compare Array[][0] (the domain name) against the mysql database and return an array with preserved values (but key preservation is not important) that only contains unique values.
Please note, that I only want to compare the first index alone, NOT the entire array.
The initial multi-dimensional array is assumed to be enormous in size (more than likely anywhere from 100k to 10 million results). What is the best way to get data back that is not contained in the database?
What I am doing now is simply storing to an array, the complete list of domains from the database, then using the following function, comparing each value in the initial array against the database array. This is horribly slow and inefficient obviously.
// get result of custom comparison function
$clean = array_filter($INITIAL_LIST, function($elem) {
$wordOkay = true;
// check every word in "filter from database" list, store it only if not in list
foreach ($this->domains as $domain) {
if (stripos($elem[0], $domain) !== false) {
$wordOkay = false;
break;
}
}
return $wordOkay;
});
Some pseudo code or even actual code would be very helpful at this point.
Use the DBMS! It was made for stuff like that.
Create a temporary table temp { id (fill with array index); url (filled with url)}
Fill it with your array's data
Ideally create an index on temp.url
Query the database:
SELECT * FROM `temp` LEFT JOIN `urls`
WHERE urls.url = temp.url AND urls.url IS NULL;
(the table urls is your existing data)
Consider the following array of objects:
class Person {
public $name;
public $occupation;
public function __construct($n, $o){
$this->name = $n;
$this->occupation = $o;
}
}
$people = array(
new Person("John", "singer"),
new Person("Paul", "guitar"),
new Person("George", "bass"),
new Person("Ringo", "drums")
);
Is there any quick way to access the objects? I wouldn't mind storing them in a different datatype (as opposed to array) if another datatype could make access easier.
Example of accessing an object: I would like to now change the "Paul" object to have an occupation of singer. This is the current solution:
foreach ( $people as &$p ) {
if ( $p->name=="Paul" )
$p->occupation="singer";
}
Alternatively, I might need to access based on a different property: Let's change all the singers' names to Yoko:
foreach ( $people as &$p ) {
if ( $p->occupation=="singer" )
$p->="Yoko";
}
Another example of accessing an object, this time in order to get the occupation of Ringo:
$ringosOccupation="";
foreach ( $people as $p ) {
if ( $p->name=="Ringo" )
$ringosOccupation = $p->occupation;
}
I suppose that I could write a People class that stores each Person object in an internal array and supplies functions to change or read occupation, but if PHP has anything cleverer build in I would love to know.
Thanks.
Just index your array with the names:
$people = array(
"John" => new Person("John", "singer"),
"Paul" => new Person("Paul", "guitar"),
"George" => new Person("George", "bass"),
"Ringo" => new Person("Ringo", "drums")
);
// Paul is the new drummer:
$people["Paul"]->occupation = "drums";
It creates a little bit of redundancy, but surely that redundancy won't be more memory or compute intensive than looping over all of them to locate the one you need every time you need to modify something.
Update:
After the question was updated, it is clear that names may be non-unique or other properties needed for access. In that case, you might be better off using a database to store object state if you have to do it often. You can't escape needing to iterate over the array if it can't be uniquely indexed. It is trivially easy to make these changes in a database, but you would need to be rebuilding the objects all the time.
So, if your array is not too large, keep looping like you have been. If it meets your performance needs, its an ok method. If you have lots and lots of these to modify, and modify often, I would suggest storing them in a database and building the objects only when you need to read one out. Then you could do:
UPDATE people SET name = 'Yoko' WHERE occupation = 'singer'
Why aren't you just setting the key of the elements to the name?
$people = array(
'john' => new Person("John", "singer"),
'paul' => new Person("Paul", "guitar"),
'george' => new Person("George", "bass"),
'ringo' => new Person("Ringo", "drums"),
);
So this is a VERY long explanation.
I have a Counter-Strike: Source server, with an in-game plugin for a store. This store saves its data in a MySQL Database (for this instance, named 'store'). The store keeps track of player's money in that database (on column 'credits' in table 'users'). It stores the clients based on a 'steam_id' (unique to every client)
The format of a 'steam_id' is (example): STEAM_0:0:123456789 OR STEAM_0:1:12345789.
My page that I have displays the top 1000 users from the database (sorted by credits).
My Problem: I need to convert these ugly steam_id's to actual names.
Where I am right now:
Steam API Documentation
According to the API documentation, I have to use 'community ids' when I query the API. If I want to get more than one user, I can use commas to separate community ids in the GET string.
(http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=APIKEY&steamids=76561197960435530,76561197960435531&format=json)
I have a function that converts the steam_id's to API-acceptable ID's.
function SteamID2CommunityID($steam_id){
$parts = explode(':', str_replace('STEAM_', '' ,$id));
$communityID = bcadd(bcadd('76561197960265728', $parts['1']), bcmul($parts['2'], '2'));
return $communityID;
}
With that, I can make my list of comma separated community ids with this:
while ($row = $mysqli->fetch_assoc($request)) {
$ids .= ',' . SteamID2CommunityID($row['steamid']) . ',';
}
Now for the tricky part, all these values come back in one JSON array. I need to add something, so when I display my data, I can convert a 'steam_id' straight to a 'name' (with the existing array).
Example of an output (most keys & values are removed to make it readable)
Array (
[response] => Array
(
[players] => Array
(
[0] => Array
(
[steamid] => 76561198010207577
[personaname] => [rGA] Stainbow
)
[1] => Array
(
[steamid] => 76561197966653036
[personaname] => |K}{R|Mastarious(MNBH)
)
)
)
)
So again, how would I go about going straight from a 'steam_id' to a name?
Thank you to anybody who can provide code and/or suggestions!
This is a variant duplicate of another Stack Overflow question, which is more practical and less localized, but I might as well answer this.
Assuming that your input steam_id is $INPUT and your final output array is stored in $OUTPUT, this is the functional foreach approach that you could use to convert steam_id to personaname:
/**
* Convert steam_id to personaname
* #returns STRING The name associated with the given steam_id
* BOOL FALSE if no match was found
*/
function steamID_to_name($INPUT, $OUTPUT)
{
// This gets the relevant part of the API response.
$array = $OUTPUT['response']['players'];
// Using your function to convert `steam_id` to a community ID
$community_id = SteamID2CommunityID($INPUT);
// Linear search
foreach ($array as $array_item)
{
// If a match was found...
if ($community_id == $array_item['steamid'])
// Return the name
return $array_item['personaname'];
}
// If no match was found, return FALSE.
return false;
}
I have the following mysql db row.
id | user_id | title_1|desc_1|link_1|title_2|desc_2|link_2|
and so on up to 10
from this one row I want to remove id and user id and have the resulting multidimensional array.
the main issue is iterarating over the associative array that is returned by my query and splitting it up into arrays of 3.
Array = (
[0] = array (
[tite_1] => 'sometitle'
[desc_1] => 'description'
[link_1] => 'a link'
)
[1] = array (
[tite_2] => 'sometitle'
[desc_2] => 'description'
[link_2] => 'a link'
)
and so on how can I achieve this I am stumped!!?
You probably want to structure your table into two tables like this:
parent(id, user_id, more_fields, whatever_you_need_here)
child(parent_id, title, desc, link)
Now it'll be very easy to get the data that you want to have.
SELECT title, desc, link FROM child WHERE parent_id = 12;
Of course, parent and child should be named appropriately, e.g. user and links.
The correct answer would be to redesign your database to use 3rd normal form. You should probably drop everything and read up on database normalization before you do anything further.
A proper design would be something like:
CREATE TABLE user_has_links (
id INT PRIMARY KEY,
user_id INT,
title TEXT,
description TEXT,
link TEXT
)
To store multiple links per user, you would simply create a new row in this table per link.
The real solution here is to fix your database to normalize these columns into other tables. However, if you are not in a position to fix your database, this code will do the job:
// $output will hold your full result set
$output = array();
while ($row = mysql_fetch_assoc($result)) {
// For each row returned, add a new array to $output
$output[] = array(
// The new array consists of 10 sub-arrays with the correct
// keys and values
array (
"title"=>$row['title1'],
"desc"=>$row['desc1'],
"link"=>$row['link1']
),
array (
"title"=>$row['title2'],
"desc"=>$row['desc2'],
"link"=>$row['link2']
),
...,
...,
array (
"title"=>$row['title10'],
"desc"=>$row['desc10'],
"link"=>$row['link10']
)
);
}