I have the following which works great, but now what I want to do is if a user types [MAP] then I want to get the word MAP
I also want allow users to send things like [MAP = array("LOCATION"=>"Melbourne Australia")]
and for the PHP to make map a array so I can then send it to a function later on
I currently do the following
$map = strpos($stringtocheck, "[MAP]");
But the issue here, is if we have a number of [] with different insides like [BOLD], [INSERT] etc then it wont find it and put it in its own $
and also it means we need to know what the array is field with or anything like that
A simple regex will pull info out of square brackets:
$s = 'Yo be [diggin] [my leet] scriptzors!';
$matches = null;
preg_match_all('/\[(.*?)\]/', $s, $matches);
var_dump($matches[1]);
Result:
array(2) {
[0]=>
string(6) "diggin"
[1]=>
string(7) "my leet"
}
Example: http://codepad.viper-7.com/erBpuB
Related
I have a database and it stores discord guilds in it and the discord guilds can have emojis like ๐ถ ๐ and โข . I am having an issue though when I am trying to do a foreach on the data it just says
PHP Warning: Invalid argument supplied for foreach() in /path/to/my/php/file
I just want to either entirely remove all emojis/unicodes or just be able to show them normally within the foreach statement without a ton of work.
Foreach im using
$stmt = $conn->prepare("SELECT guilds FROM users WHERE discord_id = :discord_id");
$stmt->bindParam(':discord_id', $userdata['discord_id']);
$guildData = $stmt->fecth(PDO::FETCH_ASSOC);
$guildData = json_decode($guildData, true);
var_dump($guildData);
foreach($guildData as $g) {
echo $g;
}
Sample of the data that is in the column guilds:
[{"id": 1, "guildname": "Server Name ๐ถ"}, {"id": 2, "guildname": "Server Name"}]
I want to either keep them and show all the emojis or just entirely remove all unicode emojis and symbols.
OK I still haven't been able to figure out what you're actually trying to accomplish, but what is clear is that you don't know what your data looks like and you're fumbling in the dark trying to apply random functions and hoping that something sensible comes out of echo.
Use var_dump(). It will tell you exactly what something is down to the smallest detail. For example, var_dump($userdata['guilds']); will tell you exactly what that variable actually is and let you make an informed decision about what to do with it next.
Eg:
$input_json = '[{"id": 1, "guildname": "Server Name ๐ถ"}, {"id": 2, "guildname": "Server Name"}]';
$decoded = json_decode($input_json, true);
var_dump($input_json, $decoded);
Output:
string(83) "[{"id": 1, "guildname": "Server Name ๐ถ"}, {"id": 2, "guildname": "Server Name"}]"
array(2) {
[0]=>
array(2) {
["id"]=>
int(1)
["guildname"]=>
string(16) "Server Name ๐ถ"
}
[1]=>
array(2) {
["id"]=>
int(2)
["guildname"]=>
string(11) "Server Name"
}
}
So now I know I should be able to:
foreach( $decoded as $guild ) {
echo "Guild: " . $guild['guildname'] . "\n";
}
Which gets me:
Guild: Server Name ๐ถ
Guild: Server Name
and if you want to really up your debugging game you'd want to look at using something like XDebug and an IDE that can plug into it properly.
$guildData = $stmt->fecth(PDO::FETCH_ASSOC);
Assuming you fix the typo fecth to fetch, this line will return an array. For debugging purposes, when you write
var_dump($guildData);
after that line, you will see something like this:
array(1) {
["guilds"]=>
string(32) "[{"id": 1, "guildname": "Ser...."
}
However, the json_decode() function expects a string, not an array.
To fix it you simply access the guilds field from the array:
$guildData = $stmt->fetch(PDO::FETCH_ASSOC); // returns an array
$jsonData = $guildData['guilds']; // get the 'guilds' field
$extracted = json_decode($jsonData, true); // JSON -> array
var_dump($extracted); // just for debugging
This will fix the "Invalid argument supplied for foreach()" error message. You also might have to take a look at UTF-8 all the way through to see if you have configured everything the right way to get the content in the correct format.
I would like to expand a string with one or more values which come from an array.
Desired result:
http://example.com/search/key=["Start", "USA", "Minneapolis"]&shift=false
Array:
array(2) {
[0]=>
string(8) "USA"
[1]=>
string(4) "Minneapolis"
}
PHP Code:
$myArr = ("USA", "Minneapolis");
$string = 'http://example.com/search/key=["Start",' .$myArr[0]. ']&shift=false';
Gives me this result: http://example.com/search/key=["Start", "USA"]&shift=false
How can I make it more dynamic so that more than one value can be added? I know I somehow have to use a foreach($myArr as $i){...} and concatenate the values via $string += but because my variable is in the middle of the string I'm kinda stuck with this approach.
Try the following:
$myArr = array("USA", "Minneapolis");
$string = 'http://example.com/search/key=["Start", "' . implode('", "', $myArr) . '"]&shift=false';
This will provide the expected output using implode.
Something isn't right here. You are trying to pass array data through a querystring but not in a valid array structure. This means you are either not using it as an array on the next script and you are going to having to chop and hack at it when the data gets there.
I'll make the assumption that you would like to clean up your process...
Declare an array of all of the data that you want to pass through the url's query string, then merge the new key values into that subarray. Finally, use http_build_query() to do ALL of the work of formatting/urlencoding everything then append that generated string after the ? in your url. This is THE clean, stable way to do it.
Code: (Demo)
$myArr = ["USA", "Minneapolis", "monkey=wren[h"];
$data = [
'key' => [
'Start'
],
'shift' => 'false'
];
$data['key'] = array_merge($data['key'], $myArr);
$url = 'http://example.com/search/?' . http_build_query($data);
echo "$url\n---\n";
echo urldecode($url);
Output:
http://example.com/search/?key%5B0%5D=Start&key%5B1%5D=USA&key%5B2%5D=Minneapolis&key%5B3%5D=monkey%3Dwren%5Bh&shift=false
---
http://example.com/search/?key[0]=Start&key[1]=USA&key[2]=Minneapolis&key[3]=monkey=wren[h&shift=false
*the decoded string is just to help you to visualize the output.
Then on your receiving page, you can simply and professionally access the $_GET['key'] and $_GET['shift'] data.
If you have a legitimate reason to use your original malformed syntax, I'd love to hear it. Otherwise, please use my method for the sake of clean, valid web development.
I am trying to learn the behinds of template system by creating my own and I have hit a bump...
I want to setup my template as follows:
{#layout=layoutname}
{#content}
<p>This is a paragraph</p>
{#endcontent}
But I don't know how to match {#layout= and get the layout name.
I have tried: if (preg_match('/(\{\#layout=[a-z]+\})+/', $string, $matches)) { which works ... kind of. I want to check if there are more then 1 layouts loaded to prevent errors in long files and want to count how many $matches I have and return error if more then 1 match is found but instead of getting all found layouts, it returns the same layout twice:
String used:
{#layout=app}
{#layout=main}
{#content}
<h1>{[username]} profile</h1>
<img src="{[photoURL]}" class="photo" alt="{[name]}" width="100" height="100"/>
<b>Name:</b> {[name]}<br />
<b>Age:</b> {[age]}<br />
<b>Location:</b> {[location]}<br />
{#endcontent}
and using that expression I get:
Array ( [0] => {#layout=app} [1] => {#layout=app} )
can someone please help me find my regex?
You need to use preg_match_all to get multiple matches in the same string. In this case, you want to check the $matches[1] which will be an array of capture group results. If you have more than one layout, it will have more than one element so if that's the case you know there is more than one layout declaration.
I would also change your regex to /\{\#layout=([a-z]+)\}/ which will capture only the layout name. $matches will look like:
array(2) {
[0]=>
array(1) {
[0]=>
string(20) "{#layout=layoutname}"
}
[1]=>
array(1) {
[0]=>
string(10) "layoutname"
}
}
So if count($matches[1]) > 1, you know there is more than one layout declaration. Otherwise, $matches[1][0] is your layout name.
Thanks to #SebastianProske I have found what I was looking for:
if (preg_match_all('/\{\#layout=([a-zA-Z0-9]+)*\}/', $string, $matches)) {
that is the correct if, that returns also the name and all the matches.
Thank you for your time,
Ares D.
I have a strange error with a $_GET Value. I'm using this code for a query:
array($_GET['cats'])
If I insert the get parameter manually, like: array(3,328) everything works fine. But if I use:
array($_GET['cats']) and submit the cats by URL like ?cats=3,328 it does not work. What could be the issue?
You can't plug a value like that. array($_GET['cats']) is equivalent to array('3,328'), if the value of $_GET['cats'] is 3,328. So basically, the value is a string, not a list of integers. What you want is:
explode(',', $_GET['cats'])
array($_GET['cats']) will create an array containing the single element thatโs value is the value of $_GET['cats'], no matter what value it is. In case of the string value 3,328 is would be identical to array('3,328').
If you want to turn the string value 3,328 into an array identical to array(3,328), use explode to split the string at , into strings and array_map with intval to turn each string into an integer:
$arr = array_map('intval', explode(',', $_GET['cats']));
Now this resulting array is really identical to array(3,328):
var_dump($arr === array(3,328)); // bool(true)
As others have said, $_GET['cats'] is a string as you're doing things at the moment.
However, if you change your URI querystring to ?cats[]=3,328 then $_GET['cats'] will be the array(3,328) ready for you to use.
Solution 1: Send HTTP GET parameters as an array in your URL
URL: parameters ?cats[]=3&cats[]=328
var_dump($_GET["cats"]) will result in:
array(2) {
[0]=>
string(1) "3"
[1]=>
string(3) "328"
}
Solution 2: Send numbers as one string in URL and process it with PHP
URL parameters: ?cats=3,328
... and then process it with some PHP code:
$cats = array_map("intval", explode(",", $_GET["cats"]));
var_dump($_GET["cats"]) will result in:
array(2) {
[0]=>
string(1) "3"
[1]=>
string(3) "328"
}
$_GET['cats'] is a simple string. If you want to get 3 and 328 as seperate values you need to use explode. You can than use foreach to print your exploded values.
You need to split up the GET-Parameters
$values = explode(',', $_GET['cats'])
I need to parse some CSS code like:
color: black;
font-family:"Courier New";
background:url('test.png');
color: red;
--crap;
Into:
array (
'color'=>'red',
'font-family'=>'"Courier New"',
'background'=>'url(\'test.png\')',
'--crap'=>''
)
I need to do this via PHP. I can see this done easily via regexp (well, easy to those that know it, unlike myself :-) ).
I need the resulting array to be "normalized", there should not be any trailing spaces between tokens, even if they were in the source.
Valueless css tokens should be included in the array as a key only. (see --crap)
Quotes (and values in general) should remain as is, except for extra formatting (spaces, tabs); easily removed via trim() or via the relevant regexp switch.
Please not that at this point, I specifically do not need a full CSS parser, ie, there is no need to parse blocks ( {...} ) or selectors ( a.myclass#myid ).
Oh, and considering I'll be putting this stuff in an array, it is perfectly ok if the last items ( color:red; ) completely override the original items ( color:black; ).
Here's a simple version:
$a = array();
preg_match_all('/^\s*([^:]+)(:\s*(.+))?;\s*$/m', $css, $matches, PREG_SET_ORDER);
foreach ($matches as $match)
$a[$match[1]] = isset($match[3]) ? $match[3] : null;
Sample output:
array(4) {
["color"]=>
string(3) "red"
["font-family"]=>
string(13) ""Courier New""
["background"]=>
string(15) "url('test.png')"
["--crap"]=>
NULL
}
Not tested with anything except your source data, so I'm sure it has flaws. Might be enough to get you started.
I found this few weeks back and looks interesting.
http://websvn.atrc.utoronto.ca/wsvn/filedetails.php?repname=atutor&path=/trunk/docs/include/classes/cssparser.php
Example:
$Parser = new cssparser();
$Results = $Parser->ParseStr("color: black;font-family:"CourierNew";background:url('test.png');color: red;--crap;");
Why don't take a look at CSSTidy?
You can try:
$result = array();
if(preg_match_all('/\s*([-\w]+)\s*:?\s*(.*?)\s*;/m',$input,$m))
var_dump($m);
// $m[1] contains all the properties
// $m[2] contains their respective values.
for($i=0;$i<count($m[1]);$i++) {
$result[$m[1][$i]] = $m[2][$i];
}
}