Extract specific data from a php string - php

I have a url stored in a database in the following format
index.php?main_page=product_info&cPath=1_11&products_id=568
I want to be able to extract the cPath data, 1_11 in this case, and the products id '568' to two separate variables. Note that the cPath value could vary from being a single number such as 23 to a series of numbers and underscores such as 17_25_31. If extracting the cPath is too difficult I could use the products_id once it's extracted and query the database again, but this isn't ideal as I want to avoid additional requests as much as possible.
I really don't know the best (correct) way to go about this.

A more refined approach as suggested by Robbie Averill
//first lets the the query string alone
$string=parse_url('index.php?main_page=product_info&cPath=1_11&products_id=568', PHP_URL_QUERY);
parse_str($string,$moo);
print_r($moo);
Output:
Array
(
[main_page] => product_info
[cPath] => 1_11
[products_id] => 568
)
My original suggestion.
parse_str('index.php?main_page=product_info&cPath=1_11&products_id=568',$moo);
print_r($moo);
output:
Array
(
[index_php?main_page] => product_info
[cPath] => 1_11
[products_id] => 568
)

Related

Extra (double) array fields in return value when using PDO result database

I'm accessing a MySQL database from a PHP script using the PDO library, which I haven't used before (I am more familiar with MySQLi). I'm seeing extra, unexpected fields in the result. They aren't interfering with my code, but I'd like to know where they've come from.
Here is my database call:
SELECT
author.author_id AS author_id,
author.name_last AS name_last,
author.name_first AS name_first,
author.detail AS detail
FROM join_play_author
LEFT JOIN author
ON join_play_author.author_id = author.author_id
WHERE join_play_author.play_id = :play_id
ORDER BY author.name_last
I then bind and execute successfully, and my results contain all of the fields I've requested, with the appropriate labels. However, each field occurs twice in the result set: once with the label I requested, and once with an extra auto-incremented value. For example, one result set (printed using print_r()) looks like this:
Array
(
[author_id] => 41
[0] => 41
[name_last] => Dekker
[1] => Dekker
[name_first] => Thomas
[2] => Thomas
[detail] => 0
[3] => 0
)
These double fields aren't actively interfering with my code, but they are annoying during debug and I worry that they could affect performance for large result sets, which will be a concern on the production site.
Removing the AS tags doesn't affect the result array.
Any ideas? Is this just a feature of PDO--and if so, is there any way to turn it off? I don't ever remember seeing these extra fields in MySQLi results, although it's possible I missed them.
The PHP library is probably setting PDO::FETCH_BOTH as the result. If you don't want the extra keys set in your array you would need to change it to PDO::FETCH_ASSOC. Most libraries allow you to change this without modifying code though. You will have to read the documentation on that.
Documentation on the PDO statement fetch options.
http://www.php.net/manual/en/pdostatement.fetch.php
As stated by chapka in his comment - use setAttribute to clear the results from double results:
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

Save php function in mysql

It has been my late-childhood dream to create a game, and now as I actually know how I thought I should fulfill my dream and started working on a little game project in my spare time. It's basically a combat type of game where you have up to 3 units, as well as your opponent, and you take turns ( since it's http, you know that feel ) to attack each other and cast spells and stuff. The issue I came across with is with abilities and how to store them. Basically if I were to store abilities in an array it would look something like
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
}
),
1 => array(...
);
But if I were to store abilities this way, every time I needed to fetch information about a single ability I would need to load the whole array and it's probably going to get pretty big in time, so that would be a tremendous waste of memory. So I jumped to my other option, to save the abilities in a mysql table, however I'm having issues with the effect part. How can I save a function into a mysql field and be able to run it on demand?
Or if you can suggest another way to save the abilities, I may have missed.
To answer your question related to storing arrays into database like MySQL I would like you to serialize the Array as String. The normal direct serialization not going to work because they don't deal with closure.
You need to use classes like super_closure which can serialize the methods and convert them into string. Read more here
https://github.com/jeremeamia/super_closure
$helloWorld = new SerializableClosure(function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
});
$serializedFunc = serialize($helloWorld);
Now you can create array like this:
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => $serializedFunc
));
This Array can now be saved directly, serialized or encoded to JSON.
I would recommend you to look at Redis or Memcache for caching query results and don't use MySQL to store functions.
You could have tree tables
spell
id
name
description
spell_effect
id
name
serversidescript
spell_effect_binder
spell_id
spell_effect_id
This would make sure, that your logic is in php files, where ever you would like them to be located, but all the meta of the spells, effects and how they bind together in the database. Meaning you will only load the function/script of the ones in need. Plus, giving you the possibility to append multiple effects to one spell.
//Firedamage.php
public function calculateEffects($level,$caster,$target) {
$extraDamage = 5*$level;
$randDamage = rand(10,50);
$caster->damage( $target, ($randDamage+$extraDamage) );
}
Spell_effect entry
id = 1
name = 'firedamage'
serversidescript = 'Firedamage.php'
spell
id = 1
name = 'Fireball'
description = 'Hurls a fireball at your foe'
spell_effect_binder
spell_id = 1
spell_effect_id = 1

How to do OR search

I want to search for a partial first and last name match - for example in sql
f_name LIKE J% OR l_name LIKE S%
would match John Smith or John Henry or Harry Smith .
I am assuming I may need to use the "$or" operator,
I have this so far that I believe is doing the LIKE % part properly, but I believe it is doing an "AND" search (meaning it searches for f_name LIKE J% AND l_name LIKE S% so it would only match John Smith):
$name1="J";
$name2="S";
$cursor = $this->clientCollection->find(array('f_name' => new MongoRegex('/^'.$name1.'/i'), 'l_name' => new MongoRegex('/^'.$name2.'/i') ));
Note: This will match containing as in %J%
MongoRegex('/'.$name1.'/i')
This will match starts with (notice the added ^) as in J%
MongoRegex('/^'.$name1.'/i')
$or takes an array of clauses, so you basically just need to wrap another array around your current query:
array('$or' => array(
array('f_name' => new MongoRegex('/'.$name1.'/i')),
array('l_name' => new MongoRegex('/'.$name2.'/i'))
));
Edit: the previous example missed an inner set of array() calls.
The original, wrong, example that I posted looked like this:
array('$or' => array(
'f_name' => new MongoRegex('/'.$name1.'/i'),
'l_name' => new MongoRegex('/'.$name2.'/i')
));
This is a valid query, but not a useful one. Essentially, the f_name and l_name query parts are still ANDed together, so the $or part is useless (it's only getting passed one query, so it's the same as just running that query by itself).
As for the alternative you mentioned in your comment, that one doesn't work because the outermost array in a query has to be an associative array. The confusion arises because Mongo's query syntax is JSON-like and uses a mixture of objects and arrays, but both of those structures are represented in PHP by arrays. The PHP Mongo driver basically converts PHP associative arrays to JSON objects ({ ... }), and "normal" PHP arrays to JSON arrays ([ ... ]).
The practical upshot is that "normal" PHP arrays are generally only valid when inside an associative array, like when specifying multiple values for a field. The following example from the PHP Mongo manual shows a valid usage of a "normal" array in a query:
$cursor = $collection->find(array("awards" => array('$in' => array("gold", "copper"))));

Creating address_list array in phpBB?

Can someone explain how address_list works in phpBB? I'm attempting to create a small function for automatically inserting private messages and think I have it up to this point:
We'll say my current user array looks like this:
$users = array('100','150','77','94')
where each number is a user's ID.
current address_list looks like this:
'address_list' => array ('u' => array(2 => 'to'))
Yes, it has been taken directly from http://wiki.phpbb.com/Using_phpBB3%27s_Basic_Functions#1.4.7._Inserting_Posts_and_Private_Messages
As far as I can tell, the explanation is telling me that it uses a two-dimensional array, but I don't need to send to groups, and I'm not even sure how to stick a two-dimensional array into that equation. All I want to do is send to the first userid on that list, and the BCC all the others.
Then again, phpBB's documentation has always been near-impossible for me to follow.
Any and all help is appreciated.
The format is as follows:
'address_list' => array(
'u' => array(2 => 'to', 3 => 'bcc'),
'g' => array(40 => 'to', 41 => 'bcc'),
)
u contains a mapping of user_id => recipient_type.
g contains a mapping of group_id => recipient_type.
A recipient type can be either to or bcc.
This example will send the PM to user 2 and group 40, and also send a BCC to user 3 and group 41.

Directly fetching a list from a column's data with MySQL

Let us suppose I have to deal with lots of grandmothers that have lots of cats. I have a table granny_cat :
granny_id | kitty_name
--------------------
1 Kizzy
1 Jimmy
1 Katty
2 Georges
2 Albert
3 Panther
and I want to retrieve a list of granny 1 cat's, i.e. to get something like (with php syntax)
array("Kizzy","Jimmy","Katty")
However, the query
SELECT kitty_name WHERE granny_id = 1
returns something like
array
(
array('kitty_name' => "Kizzy"),
array('kitty_name' => "Jimmy"),
array('kitty_name' => "Katty")
)
what is quite logical, as I can fetch two, or more fields with a similar query. I can obviously map this array to get what I want, however, I wonder whether there is a (simple) way to get it directly from mysql, or not.
Thanks.
SELECT GROUP_CONCAT(kitty_name)
FROM mytable
WHERE granny_id = 1
will give you the comma-delimited list which you can explode into an array.
MySQL does not support native array datatype. In PostgreSQL you would be able to do the following:
SELECT ARRAY
(
SELECT kitty_name
FROM mytable
WHERE granny_id = 1
) AS kitties
, which would give you a native PHP array.
A wrapper library will typically handle this, e.g. ADODb has the GetCol() method:
$names=$db->GetCol('SELECT kitty_name WHERE granny_id = 1');

Categories