I'm trying to do a PHP find over a MongoDB collection using MongoRegex, but I'm not able to make it work. The code is quite easy:
$cursor = $this->collection->find($params)
//$params has this value:
//Array
//(
// [name] => MongoRegex Object
// (
// [regex] => .*victor.*
// [flags] => i
// )
// [login] => MongoRegex Object
// (
// [regex] => .*victor.*
// [flags] => i
// )
//)
This $params array is constructed with this function:
function toRegEx($entryVars=array()){
$regexVars = array();
foreach($entryVars as $var => $value){
$regexVal = html_entity_decode($value);
$regexVars[$var] = new MongoRegex("/.*".$regexVal.".*/i");
}
return $regexVars;
}
For some reason, this query is only returning the values which makes an exact match (i.e. the documents where login or name are exactly "victor"). What I want is that the query returns all the documents where login and/or name contains the word "victor". I'm pretty sure I'm missing something basic, but I'm not being able to find it. Any help is appreciated. Thanks!
I suppose you simply anchored the regexp to the beginning of the subject string (^), try without :
$regexVars[$var] = new MongoRegex("/".$regexVal."/i");
EDIT:
Also, if the print_r dump of the $params array above is accurate, you're probably missing a $or statement somewhere to reflect your conditions. By default, the mongodb query criteria are linked with a "and" logic, so your query will return records matching regexps on both fields only.
Related
I'm trying to dynamically generate a nested array by pulling polygon data from a database using the Pods Framework, however I'm struggling to get the formatting / syntax right (I'm not an expert when it comes to PHP).
This is my code, where "polygon_latlon" is the field containing pairs of latitude and longitude points within double quotes separated by commas which make up the (irregular) polygons:
$lines = array();
//set find parameters
$params = array(
'limit' => -1
);
//get pods object
$maps = pods( 'maps_osexplorer', $params );
//loop through records
if ( $maps->total() > 0 ) {
while ( $maps->fetch() ) {
$polygon1 = $maps->field('polygon_latlon');
$lines[] = "array($polygon1)";
}
}
$polygons1 = implode(',', $lines);
Using print_r($lines) outputs in this format:
Array (
[0] => array(“54.8209937901589 -5.1847118669456265″,”54.82875805834827 -4.873857026861909″,”55.03518041767634 -4.888625345496792″,”55.02735680301253 -5.201071164745328″,”54.8209937901589 -5.1847118669456265”)
[1] => array(“54.73307781328839 -5.107888813651375″,”54.73542913841878 -5.014843407073816″,”54.62773859547211 -5.006866177191955″,”54.63292697997008 -4.790281966946296″,”54.839371033206184 -4.804517368244679″,”54.831783194724316 -5.115474120227528″,”54.73307781328839 -5.107888813651375”)
[2] => array(“54.66161594261056 -4.714709589503054″,”54.66230647443063 -4.683739691903676″,”54.68026002182563 -4.684924716676078″,”54.679569033955396 -4.715908247171228″,”54.66161594261056 -4.714709589503054”)
[3] => array(“54.79285752469713 -4.871307801664465″,”54.799816987439904 -4.560586644307456″,”55.06913330516994 -4.577766586876797″,”55.06210435522974 -4.890565603716853″,”54.79285752469713 -4.871307801664465”)
[4] => array(“54.76588200465172 -4.675046760686505″,”54.767570233715865 -4.597418172482791″,”54.66433060233055 -4.590822213183797″,”54.66967882431423 -4.327495656368091″,”54.93904807902748 -4.34303745757995″,”54.93194793898191 -4.686064981190482″,”54.76588200465172 -4.675046760686505”)
etc
etc
);
Using print_r($polygons1) outputs in this format:
array(“54.8209937901589 -5.1847118669456265″,”54.82875805834827 -4.873857026861909″,”55.03518041767634 -4.888625345496792″,”55.02735680301253 -5.201071164745328″,”54.8209937901589 -5.1847118669456265”),
array(“54.73307781328839 -5.107888813651375″,”54.73542913841878 -5.014843407073816″,”54.62773859547211 -5.006866177191955″,”54.63292697997008 -4.790281966946296″,”54.839371033206184 -4.804517368244679″,”54.831783194724316 -5.115474120227528″,”54.73307781328839 -5.107888813651375”),
array(“54.66161594261056 -4.714709589503054″,”54.66230647443063 -4.683739691903676″,”54.68026002182563 -4.684924716676078″,”54.679569033955396 -4.715908247171228″,”54.66161594261056 -4.714709589503054”),
array(“54.79285752469713 -4.871307801664465″,”54.799816987439904 -4.560586644307456″,”55.06913330516994 -4.577766586876797″,”55.06210435522974 -4.890565603716853″,”54.79285752469713 -4.871307801664465”),
array(“54.76588200465172 -4.675046760686505″,”54.767570233715865 -4.597418172482791″,”54.66433060233055 -4.590822213183797″,”54.66967882431423 -4.327495656368091″,”54.93904807902748 -4.34303745757995″,”54.93194793898191 -4.686064981190482″,”54.76588200465172 -4.675046760686505”),
etc
etc
What I need it to output, but I can't quite find the right code / syntax for, is:
array(
array(“54.8209937901589 -5.1847118669456265″,”54.82875805834827 -4.873857026861909″,”55.03518041767634 -4.888625345496792″,”55.02735680301253 -5.201071164745328″,”54.8209937901589 -5.1847118669456265”),
array(“54.73307781328839 -5.107888813651375″,”54.73542913841878 -5.014843407073816″,”54.62773859547211 -5.006866177191955″,”54.63292697997008 -4.790281966946296″,”54.839371033206184 -4.804517368244679″,”54.831783194724316 -5.115474120227528″,”54.73307781328839 -5.107888813651375”),
array(“54.66161594261056 -4.714709589503054″,”54.66230647443063 -4.683739691903676″,”54.68026002182563 -4.684924716676078″,”54.679569033955396 -4.715908247171228″,”54.66161594261056 -4.714709589503054”),
array(“54.79285752469713 -4.871307801664465″,”54.799816987439904 -4.560586644307456″,”55.06913330516994 -4.577766586876797″,”55.06210435522974 -4.890565603716853″,”54.79285752469713 -4.871307801664465”),
array(“54.76588200465172 -4.675046760686505″,”54.767570233715865 -4.597418172482791″,”54.66433060233055 -4.590822213183797″,”54.66967882431423 -4.327495656368091″,”54.93904807902748 -4.34303745757995″,”54.93194793898191 -4.686064981190482″,”54.76588200465172 -4.675046760686505”),
etc
etc
);
i.e. I need the output from print_r($polygons1) nested within another array. How would I achieve this?
Ultimately I don't want to print the nested array but store it as a variable for use in another section of code.
Sorry I am little late but you can do it with the following piece of code,
$var = array($polygons1)
Using json_decode, I've ended up with an object that looks like this:
$data->foo->bar->1234567->id
I want to access id. There are two problems, both with the number 1234567:
It's an illegal property name.
The number will differ each time, and I can't predict what the number will be. I need a way of accessing id, even when I don't know the number.
I know I can overcome problem (1) with curly braces, but I don't know how to overcome (2). I don't want to use get_object_vars, because the object is likely to be very large, and that function is very slow.
My current solution is simply
foreach ($data->foo->bar as $id); but that feels rather hacky. Is there a better way?
From my comment above, using json_decode(,true) and then resetting.
The example json array looks like:
Array (
[foo] => Array (
[bar] => Array (
[1234567] => Array (
[id] => 1234
)
)
)
)
The code:
<?php
$data = json_decode('{"foo":{"bar":{"1234567":{"id":1234}}}}', true);
reset($data['foo']['bar']);
$number = key($data['foo']['bar']);
echo $data['foo']['bar'][$number]['id'];
Output: 1234
In case you don't need the whole array anymore and only want to get the id you can get it like this:
<?php
$data = json_decode('{"foo":{"bar":{"1234567":{"id":1234}}}}', true);
echo array_shift($data['foo']['bar'])['id'];
Only works if the unknown key is the first element of bar. array_shift removes the element from $data.
Usually when I search for one related ID I do it like this:
$thisSearch = $collection->find(array(
'relatedMongoID' => new MongoId($mongoIDfromSomewhereElse)
));
How would I do it if I wanted to do something like this:
$mongoIdArray = array($mongoIDfromSomewhereElseOne, $mongoIDfromSomewhereElseTwo, $mongoIDfromSomewhereElseThree);
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => new MongoId(mongoIdArray)
)));
I've tried it with and without the new MongoId(), i've even tried this with no luck.
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
how do I search '$in' "_id" when you need to have the new MongoID() ran on each _id?
Hmm your rtying to do it the SQL way:
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
Instead try:
$_ids = array();
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
That should produce a list of ObjectIds that can be used to search that field - relatedMongoID.
This is what I am doing
Basically, as shown in the documentation ( https://docs.mongodb.org/v3.0/reference/operator/query/in/ ) the $in operator for MongoDB in fact takes an array so you need to replicate this structure in PHP since the PHP driver is a 1-1 with the documentation on most fronts (except in some areas where you need to use an additional object, for example: MongoRegex)
Now, all _ids in MongoDB are in fact ObjectIds (unless you changed your structure) so what you need to do to complete this query is make an array of ObjectIds. The ObjectId in PHP is MongoId ( http://php.net/manual/en/class.mongoid.php )
So you need to make an array of MongoIds.
First, I walk through the array (could be done with array_walk) changing the values of each array element to a MongoId with the old value encapsulated in that object:
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
I use a ternary operator here to see if the value is already a MongoId encapsulated value, and if not encapsulate it.
Then I add this new array to the query object to form the $in query array as shown in the main MongoDB documentation:
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
So now when the query is sent to the server it forms a structure similar to:
{relatedMongoId: {$in: [ObjectId(''), ObjectId('')]}}
Which will return results.
Well... I came across the same issue and the solution might not be relevant anymore since the API might have changed. I solved this one with:
$ids = [
new \MongoDB\BSON\ObjectId('5ae0cc7bf3dd2b8bad1f71e2'),
new \MongoDB\BSON\ObjectId('5ae0cc7cf3dd2b8bae5aaf33'),
];
$collection->find([
'_id' => ['$in' => $_ids],
]);
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;
}
To pass variables into functions, I do the following (as other people I'm sure):
function addNums($num1, $num2)
{
$num1 + $num2;
}
addNums(2, 2);
My question is how would I structure a function to act like Wordpress:
wp_list_categories('title_li=');
Essentially I am looking for a way to create a key/value pair in my functions.
Any advice is appreciated.
parse_str() should do what you want: http://www.php.net/parse_str
You can use parse_str to parse the string for arguments. The tricky thing is that you may not want to just allow any and all parameters to get passed in. So here's an example of only allowing certain parameters to be used when they're passed in.
In the following example, only foo, bar and valid would be allowed.
function exampleParseArgs($arg_string) {
// for every valid argument, include in
// this array with "true" as a value
$valid_arguments = array(
'foo' => true,
'bar' => true,
'valid' = true,
);
// parse the string
parse_str($arg_string, $parse_into);
// return only the valid arguments
return array_intersect_key($parse_into,$valid_arguments);
}
baz will be dropped because it is not listed in $valid_arguments. So for this call:
print_r(exampleParseArgs('foo=20&bar=strike&baz=50'));
Results:
Array
(
[foo] => 20
[bar] => strike
)
Additionally, you can browse the Wordpress Source code here, and of course by downloading it from wordpress.org. Looks like they do something very similar.