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)
Related
I run a gaming server and it keeps some information in a database.
I run a MySQL query that pulls information like cargo_items (below).
How can I format this data properly in PHP? I'd like for it to be in a table. Is that possible? My knowledge of handing arrays like this is limited do to the complex nature. This is how the data is returned from the database.
Array
(
[0] => Array
(
[0] => Array
(
[id] => 2237
[cargo_weapons] =>
[
["MMG_02_black_F","","","",[],""],
["arifle_SDAR_F","","","",[],""],
["arifle_SDAR_F","","","",[],""],
["arifle_SPAR_03_khk_F","","","",[],""],
["LMG_Zafir _F","","","",[],""],
["MMG_02_black_F","","","",[],""],
["MMG_02_black_F","","","",[],""]
]
)
)
)
The output should be a table:
Weapons
-------
MMG_02_black_F
arifle_SDAR_F
arifle_SDAR_F
arifle_SPAR_03_khk_F
LMG_Zafir_F
MMG_02_black_F
MMG_02_black_F
Since you have multidimensional array, you need custom recursion function, or, in your specific case, you could use something like this:
function get_items($item, $key)
{
if(!empty($item) && $key=='cargo_weapons')
//your html table cells
echo "$item<br>";
}
array_walk_recursive($array, 'get_items');
array_walk_recursive
will do the job (this function returns true or false), but you can (ab)use it to display desired HTML too.
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 am trying to come up with a means of working with what could potentially be very large array sets. What I am doing is working with the facebook graph api.
So when a user signs up for a service that I am building, I store their facebook id in a table in my service. The point of this is to allow a user who signs up for my service to find friends of their's who are on facebook and have also signed up through my service to find one another easier.
What I am trying to do currently is take the object that the facebook api returns for the /me/friends data and pass that to a function that I have building a query to my DB for the ID's found in the FB data which works fine. Also while this whole bit is going on I have an array of just facebook id's building up so I can use them in an in_array scenario. As my query only returns facebook id's found matching
While this data is looping through itself to create the query I also update the object to contain one more key/value pair per item on the list which is "are_friends"=> false So far to this point it all works smooth and relatively fast, and I have my query results. Which I am looping over.
So I am at a part where I want to avoid having a loop within a loop. This is where the in_array() bit comes in. Since I created the array of stored fb id's I can now loop over my results to see if there's a match, and in that event I want to take the original object that I appended 'are_friends'=>false to and change the ones in that set that match to "true" instead of false. I just can't think of a good way without looping over the original array inside the loop that is the results array.
So I am hoping someone can help me come up with a solution here without that secondary loop
The array up to this point that starts off as the original looks like
Array(
[data](
[0] => array(
are_fb_friends => false
name => user name
id => 1000
)
[1] => array(
are_fb_friends => false
name => user name
id => 2000
)
[2] => array(
are_fb_friends => false
name => user name
id => 3000
)
)
)
As per request
This is my current code logic, that I am attempting to describe above..
public function fromFB($arr = array())
{
$new_arr = array();
if((is_array($arr))&&(count($arr) > 0))
{
$this->db->select()->from(MEMB_BASIC);
$first_pass = 0;
for($i=0;$i < count($arr);$i++)
{
$arr[$i]['are_fb_friends'] = "false";
$new_arr[] = $arr[$i]['id'];
if($first_pass == 0)
{
$this->db->where('facebookID', $arr[$i]['id']);
}
else
{
$this->db->or_where('facebookID', $arr[$i]['id']);
}
$first_pass++;
}
$this->db->limit(count($arr));
$query = $this->db->get();
if($query->num_rows() > 0)
{
$result = $query->result();
foreach($result as $row)
{
if(in_array($row->facebookID, $new_arr))
{
array_keys($arr, "blue");
}
}
}
}
return $arr;
}
To search a value and get its key in an array, you can use the array_search function which returns the key of the element.
$found_key = array_search($needle, $array);
For multidimensional array search in PHP look at https://stackoverflow.com/a/8102246/648044.
If you're worried about optimization I think you have to try using a query on a database (with proper indexing).
By the way, are you using the Facebook Query Language? If not give it a try, it's useful.
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 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?