How to remove wrong schema from an URL (with PHP) - php

I need to remove a wrong schema from an URL submitted as a string.
I start with this consideration:
The only two allowed schemas are http:// and https://
Starting from this consideration, I need to remove from the string all wrongly formatted schemas like:
htp://example.com
htps://example.com
http:/example.com
https:/example.com
htpexample.com
htps://example.com
http:/example.com
https:/example.com
... many many more ...
My questions are:
Is there a way to calculate all possible variation of wrong schemas?
Which is the best approach to remove them from the given string?
ABOUT QUESTION 2
My first approach would be to create an array with all the wrong schemas and then use something like this:
$wrongSchemas = [/* here all the possible wrong schemas calculated from question 1 */];
$url = str_replace($wrongSchemas, '', $url);
But this approach relies on a correct order, because instead I risk to remove partial schemas and make it wrong anyway.
And anyway I need to find a way to create the array $wrongSchemas!
Any suggestion or any further consideration on the topic that I'm missing, is well appreciated.

use strpos check in your $url
if(strpos($url,"http://")!==0 && strpos($url,"https://")!==0){
//wrong schemas
$exp_string = "";
// $exp_string = strpos($url,"//")?"//":"/";
if(strpos($url,"://"))
$exp_string = "://";
elseif(strpos($url,":/"))
$exp_string = ":/";
elseif(strpos($url,":"))
$exp_string = ":";
elseif(strpos($url,"//"))
$exp_string = "//";
$temp = explode($exp_string,$url);
if(count($temp)>1){
$url = '';
for($i=1;$i<count($temp);$i++){
$url = $url.$temp[$i];
}
//if needed you can add http:// here: $url = 'http://'.$url;
}
}
echo $url;
//process for right schemas
If you need more validations like url starting with ht,htp,etc you can use checkdnsrr or gethostbyname functions to validate domains

After some more thoughts, thanks also to some of your comments (thank you #Frédéric Clausset), I decided that the best approach would be to build the array of wrong schemas on the fly:
$schemas = ['http', 'htp', 'htt', 'ht', 'hp', 'ttp', 'tp'];
$delimiters = ['://', ':/', ':', '//', '/'];
$wrongCombinations = [];
foreach ($schemas as $wrongSchema) {
foreach ($delimiters as $wrongDelimiter) {
$combination = $wrongSchema . $wrongDelimiter;
$combinationSecure = $wrongSchema . 's' . $wrongDelimiter;
if ('http://' !== $combination) {
$wrongCombinations[] = $combination;
}
if ('https://' !== $combinationSecure) {
$wrongCombinations[] = $combinationSecure;
}
}
}
This generates a long array like this:
array:68 [▼
0 => "http:/"
1 => "https:/"
2 => "http:"
3 => "https:"
4 => "http//"
5 => "https//"
6 => "http/"
7 => "https/"
8 => "htp://"
9 => "htps://"
10 => "htp:/"
11 => "htps:/"
12 => "htp:"
13 => "htps:"
14 => "htp//"
15 => "htps//"
16 => "htp/"
17 => "htps/"
18 => "htt://"
19 => "htts://"
20 => "htt:/"
21 => "htts:/"
22 => "htt:"
23 => "htts:"
24 => "htt//"
25 => "htts//"
26 => "htt/"
27 => "htts/"
28 => "ht://"
29 => "hts://"
30 => "ht:/"
31 => "hts:/"
32 => "ht:"
33 => "hts:"
34 => "ht//"
35 => "hts//"
36 => "ht/"
37 => "hts/"
38 => "hp://"
39 => "hps://"
40 => "hp:/"
41 => "hps:/"
42 => "hp:"
43 => "hps:"
44 => "hp//"
45 => "hps//"
46 => "hp/"
47 => "hps/"
48 => "ttp://"
49 => "ttps://"
50 => "ttp:/"
51 => "ttps:/"
52 => "ttp:"
53 => "ttps:"
54 => "ttp//"
55 => "ttps//"
56 => "ttp/"
57 => "ttps/"
58 => "tp://"
59 => "tps://"
60 => "tp:/"
61 => "tps:/"
62 => "tp:"
63 => "tps:"
64 => "tp//"
65 => "tps//"
66 => "tp/"
67 => "tps/"
]
Those 68 combinations are all the possible wrong ones.
Now, a simple str_replace removes the schema if it is one of the wrong ones:
str_replace($combinations, '', $domain);
This intercept wrong URLs like:
htp://example.com > example.com
http:/example.com > example.com
htps:/example.com > example.com
hps:/example.com > example.com
htp:example.com > example.com
many many more
all possible variations
Thank you to all of you for your answers that helped me to better clarify the problem and find my solution! :)
PS
If you find bugs or drawbacks in this code, please, let me know!

I would search for :// if exists in string, after a then a simple in_array with the substring
$url="https://www.example.com";
$validschemas=array("http","https");
$pos=strpos($url,"://");
if($pos)
{
$valid=in_array(substr($url,0,$pos),$validschemas)?true:false;
//If not valid schema, remove schema from url, if it os ok dont touch it.
if(!$valid)
$url=substr($url,$pos+3);
}
else
{
//No schema, then url continues being the same
}

Related

I want to remove the common elements in two arrays using PHP [duplicate]

This question already has answers here:
How to remove an array value from another array using PHP question
(3 answers)
Closed 2 years ago.
I tried the following code and it should be working, but not getting the required result. What's wrong with the code? I have two arrays and I want to remove the common elements in both arrays so I wore the following code.
<?php
$aMgaMembersList= array (
0 => '9194962',
1 => '9197448',
2 => '9174039',
3 => '9199473',
4 => '9175598',
5 => '9197474',
6 => '9195444',
7 => '9195268',
8 => '9189438',
9 => '9175103',
10 => '9199619',
11 => '9195267',
12 => '9194463',
13 => '9196333',
14 => '9197471',
15 => '9198479',
16 => '9197472',
17 => '9185479',
18 => '9197452',
19 => '9197442',
20 => '9180861',
21 => '9194950',
22 => '9198464',
23 => '9199613',
24 => '9175939',
25 => '9195442',
26 => '9190203',
27 => '9199613',
) ;
$aRocketMembersList = array (
0 => '9174039',
1 => '9175103',
2 => '9175598',
3 => '9175939',
4 => '9180861',
5 => '9185479',
6 => '9189438',
7 => '9190203',
8 => '9194463',
9 => '9194950',
10 => '9194962',
11 => '9195267',
12 => '9195268',
13 => '9195442',
14 => '9195444',
15 => '9196333',
16 => '9197442',
17 => '9197448',
18 => '9197452',
19 => '9197471',
20 => '9197472',
21 => '9197474',
22 => '9198464',
23 => '9198479',
24 => '9199473',
25 => '9199613',
26 => '9199619',
27 => 'arun',
) ;
if (is_array($aRocketMembersList)) {
foreach ($aRocketMembersList as $rocketUsername) {
if (in_array($rocketUsername, $aMgaMembersList)) {
unset($aMgaMembersList[array_search($rocketUsername, $aMgaMembersList)]);
unset($aRocketMembersList[array_search($rocketUsername, $aRocketMembersList)]);
}
}
}
print_r($aRocketMembersList);
print_r($aMgaMembersList);
The out put is
Array
(
[27] => arun
)
Array
(
[27] => 9199613
)
The element 9199613 shouldn't be there. Why it's happening? I ran the code in a different environment and the result is same.
Here's a different function that works regardless of the order of Arrays:
<?php
function different($array1, $array2){
$m = array_merge($array1, $array2); $x = array_intersect($array1, $array2); $a = array_diff($m, $x); $b = array_diff($x, $m); $a = array_merge($a, $b);
$r = [];
foreach($a as $v){
$o = new StdClass; $k = array_search($v, $array1);
if($k === false)$k = array_search($v, $array2);
$o->$k = [$array1[$k], $array2[$k]]; $r[] = $o;
}
return $r;
}
$aMgaMembersList = [
0 => '9194962',
1 => '9197448',
2 => '9174039',
3 => '9199473',
4 => '9175598',
5 => '9197474',
6 => '9195444',
7 => '9195268',
8 => '9189438',
9 => '9175103',
10 => '9199619',
11 => '9195267',
12 => '9194463',
13 => '9196333',
14 => '9197471',
15 => '9198479',
16 => '9197472',
17 => '9185479',
18 => '9197452',
19 => '9197442',
20 => '9180861',
21 => '9194950',
22 => '9198464',
23 => '9199613',
24 => '9175939',
25 => '9195442',
26 => '9190203',
27 => '9199613'
];
$aRocketMembersList = [
0 => '9174039',
1 => '9175103',
2 => '9175598',
3 => '9175939',
4 => '9180861',
5 => '9185479',
6 => '9189438',
7 => '9190203',
8 => '9194463',
9 => '9194950',
10 => '9194962',
11 => '9195267',
12 => '9195268',
13 => '9195442',
14 => '9195444',
15 => '9196333',
16 => '9197442',
17 => '9197448',
18 => '9197452',
19 => '9197471',
20 => '9197472',
21 => '9197474',
22 => '9198464',
23 => '9198479',
24 => '9199473',
25 => '9199613',
26 => '9199619',
27 => 'arun'
];
$diffArray = different($aMgaMembersList, $aRocketMembersList);
$test = json_encode($diffArray);
?>
$tmp1 = array_diff($aMgaMembersList,$aRocketMembersList);
$tmp2 = array_diff($aRocketMembersList,$aMgaMembersList);
$final = array_unqiue(array_merge($tmp1, $tmp2));
unset($tmp1);unset($tmp2);//and maybe original arrays?
There are probably better solutions, but that should work for you. If you had associative arrays instead of numeric values you could exclude array_unqiue
EDIT:
I originally assumed you wanted the results in one array, if that's unnecessary just use the array_diff function twice, and you can maintain your original array names as desired. Again there are probably better solutions (more memory/processor efficient), but in most practical cases this will be fine. If you're working with extremely large data sets... do more research ;)

Array - Select the sub children id's from an array

I have this array built from a function that sorts allowed or valid url slugs and their ids into another array. I can call the current category id by passing the url slug to the category. Now I need to get the children category ids (if any) so i can call the appropriate items from the database for display purpose.
Heres an example of the array:
Array (
[radios] => 1
[radios/motorola] => 2
[radios/motorola/handheld] => 3
[radios/motorola/mobile] => 4
[radios/icom] => 5
[radios/icom/handheld] => 6
[radios/icom/mobile] => 7
[radios/mics-and-speakers] => 8
[radios/mounts] => 9
[radios/radio-other] => 10
[misc] => 11
[misc/led] => 12
[phones] => 13
[phones/samsung] => 14
[phones/lg] => 15
[phones/motorola] => 16
[phones/huawei] => 17
[phones/blackberry] => 18
[phones/flip] => 19
[boosters] => 20
[boosters/standalone] => 21
[boosters/indoor-antenna] => 22
[boosters/outdoor-antenna] => 23
[boosters/connections] => 24
[accessories] => 25
[accessories/cases] => 26
[accessories/other] => 27
[internet] => 28
[internet/fusion] => 29
[internet/point-to-point] => 30
[internet/hotspots] => 31
[internet/gateways] => 32
[internet/switches] => 33
[cameras] => 34
[cameras/complete-kits] => 35
[cameras/additional-cameras] => 36
[cameras/other] => 37
);
As you can see, each result points to the category ID of that group. If i visit the following url:
http://example.com/store/cameras
I can print out that THE PATH CURRENTLY IS: 34 which is correct. Since It has children under it, I also need their ID's and the ID's of any of their children, etc etc. That way on radios, i can show ALL of the sub category items, and on radios/motorola i am only showing the Motorola based items and its children, and such down the line.
If there an easy way, using this array I have now, to sort the children (if any) all the way down and get back just their id's (preferably in a new array) for showing database items?
You might want to create a function like this to filter your array,
function filterArray($array, $term) {
$pattern = "/\b" . str_replace($term, '/', '\/') . "\b/i";
foreach($array as $key => $value) {
if(preg_match($pattern, $key)) {
/* Following condition makes sure that your search
will match starting from the beginning. */
if (stripos(trim($key), $term) === 0){
$filtred[] = $value;
}
}
}
}
Then call the above function with the $array and your search $term.
filterArray($array, 'radios') will give you this,
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 [9] => 10 )
filterArray($array, 'radios/motorola') will give you this,
Array ( [0] => 2 [1] => 3 [2] => 4 )
And so on.. I hope this helps.
You can maybe try double layer array, so that you can store values like this,
Array (
[name] => John
[surname] => Smith
[contact] => Array (
[address] => 18 Maple Street
[number] => 555 477 77 77
)
)
This way if you need to print something from "contact" you can use a loop and print all childs of contact field.

Creating A Web Game Having Issues With A Function

I'm currently working on a game for browsers strictly built with php, html, sql & js atm. It's just a fun project i'm working on. Yet I have come to a spot where a function is not working as intended and maybe some help can help me find where I am going wrong. So with that said I have a page where you can fight enemies. Now once you hit the attack button it calculates a formula then updates the enemy health according to the enemies current health - so called formula. Now that works as intended. I moved on to then make the opposite (when an enemy attacks me) and it is not working as intended. It always, no matter what, sets the character health to 0 instead of running the correct formula etc. $enemy & $my_character are arrays.
$enemy = Array ( [level] => 1 [cur_health] => 104 [max_health] => 108 [cur_mana] => 36 [max_mana] => 36 [defense] => 30 [attack_power] => 16 [spell_power] => 3 [image] => images/enemies/demon_1.png [name] => Demon [battleback] => images/battlebacks/cave1.png )
$my_character = Array ( [name] => rackemup [level] => 1 [next_level] => 2 [avatar] => 05.png [class] => Knight [race] => Human [max_health] => 135 [current_health] => 135 [max_mana] => 9 [current_mana] => 9 [next_level_xp] => 100 [current_xp] => 30 [sp] => 0 [gold] => 115 [tokens] => 0 [ac] => 0 [defense] => 18 [attack_power] => 20 [spell_power] => 1 )
Controller:
if ($action == "attack") {
charAttack($enemy,$my_character);
enemyAttack($enemy,$my_character);
header("Location: ?route=$route&msg=2#attack");
exit;
}
Model:
function enemyAttack($enemy,$my_character) {
$dmg = $enemy['attack_power'] - $my_character['defense'];
if ($dmg <= 0) {
$dmg = 1;
}else{
$dmg = ceil($dmg);
}
$cur_hp = $my_character['cur_health'] - $dmg;
updateCharacter($_SESSION['char'],"health",$cur_hp);
updateLog("Enemy Attack","The Enemy Hit You For ".number_format($dmg)." Damage!");
}
function charAttack($enemy,$my_character) {
$dmg = $my_character['attack_power'] - $enemy['defense'];
if ($dmg <= 0) {
$dmg = 1;
}else{
$dmg = ceil($dmg);
}
$cur_hp = $enemy['cur_health'] - $dmg;
updateEnemy($_SESSION['char'],"health",$cur_hp);
updateLog("User Attack","Your Attack Hit The Enemy For ".number_format($dmg)." Damage!");
}
Try $my_character['current_health'] instead of $my_character['cur_health'] in enemyAttack? ;-)

Traversing XML structure in PHP

How can I read the state in this object of an array
I am getting this result when I
$xml = simplexml_load_string($xml_string);
display_output($xml->country[0]);
RESULT:
SimpleXMLElement::__set_state(array(
'#attributes' =>
array (
'name' => 'Afghanistan',
),
'state' =>
array (
0 => 'Badakhshan',
1 => 'Badghis',
2 => 'Baghlan',
3 => 'Balkh',
4 => 'Bamian',
5 => 'Farah',
6 => 'Faryab',
7 => 'Ghazni',
8 => 'Ghowr',
9 => 'Helmand',
10 => 'Herat',
11 => 'Jowzjan',
12 => 'Kabol',
13 => 'Kandahar',
14 => 'Kapisa',
15 => 'Konar',
16 => 'Kondoz',
17 => 'Laghman',
18 => 'Lowgar',
19 => 'Nangarhar',
20 => 'Nimruz',
21 => 'Oruzgan',
22 => 'Paktia',
23 => 'Paktika',
24 => 'Parvan',
25 => 'Samangan',
26 => 'Sar-e Pol',
27 => 'Takhar',
28 => 'Vardak',
29 => 'Zabol',
),
))
I would like to get the state, how can I do it? I have tried, unfortunately it is not working.
$a = $xml->country[0]->state[0];
*below is the xml:
<?xml version="1.0" encoding="utf-8"?>
<countries>
<country name="Afghanistan">
<state>Badakhshan</state>
<state>Badghis</state>
<state>Baghlan</state>
<state>Balkh</state>
<state>Zabol</state>
</country>
</countries>
Update, found the answer:
$xml = simplexml_load_string($xml_string);
$country = array();
$state = array();
for($x=0;$x<count($xml);$x++)
{
$country[] = (string)$xml->country[$x]->attributes()->name;
if(isset($xml->country[$x]->state))
{
for($y=0;$y<count($xml->country[$x]->state);$y++)
{
$state[$x][] = (string)$xml->country[$x]->state[$y];
}
}
}
return array($country,$state);
I would think you would use xpath to look for the attribute "Afghanistan" on a country element, since you know this is the country you are looking to get data for.
$afghanistan = $xml->xpath("//country[#name='Afghanistan']");
$afghan_states = $afghanistan->state;
$first_state = $afghan_states[0];
Or if you don't need the country level information, you could use a more specific xpath selector:
$afghan_states = $xml->xpath("//country[#name='Afghanistan']/state");
$first_state = $afghan_states[0];
This would make your code work even if there were changes in country element ordering in the XML.

PHP if() not working as designed? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is a little bit confusing on why this won't work. I can do a work around, but any ideas? It's to match an uploaded CSV to a configuration in a database. Returns only the first 5 columns. The rest, user specified ones (should print Echo) do not show up.
$csv_col while looping =
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
$getConfiguration[0] =
Array
(
[config_key] => 22
[config_client_ident] => 105
[config_s_timestamp] => 1378008000
[config_e_timestamp] =>
[config_kpi_1] => 81
[config_kpi_2] => 82
[config_kpi_3] => 83
[config_kpi_4] => 84
[config_kpi_5] =>
[config_kpi_6] =>
[config_kpi_7] =>
[config_kpi_8] =>
[config_kpi_9] =>
[config_kpi_10] =>
[config_kpi_11] =>
[config_kpi_12] =>
[config_kpi_13] =>
[config_kpi_14] =>
[config_kpi_15] =>
[config_kpi_16] =>
[config_kpi_17] =>
[config_kpi_18] =>
[config_kpi_19] =>
[config_kpi_20] =>
[config_kpi_21] =>
[config_kpi_22] =>
[config_kpi_23] =>
[config_kpi_24] =>
[config_kpi_25] =>
[config_kpi_26] =>
[config_kpi_27] =>
[config_kpi_28] =>
[config_kpi_29] =>
[config_kpi_30] =>
[config_kpi_31] =>
[config_kpi_32] =>
[config_kpi_33] =>
[config_kpi_34] =>
[config_kpi_35] =>
[config_kpi_36] =>
[config_kpi_37] =>
[config_kpi_38] =>
[config_kpi_39] =>
[config_kpi_40] =>
[config_kpi_41] =>
[config_kpi_42] =>
[config_kpi_43] =>
[config_kpi_44] =>
[config_kpi_45] =>
[config_kpi_46] =>
[config_kpi_47] =>
[config_kpi_48] =>
[config_kpi_49] =>
[config_kpi_50] =>
)
$csvRead[0]
Array
(
[0] => Data Date
[1] => Agent IDENT
[2] => Client IDENT
[3] => Location IDENT
[4] => Program IDENT
[5] => xx VSAT
[6] => xx SWSAT
[7] => xx NSODS
[8] => xx SWDSAT
)
Returned from query
Array
(
[0] => Array
(
[key_id] => 84
[key_enabled] => 1
[key_name] => xx SWDSAT
[key_desc] => xx CSAT Somewhat Dissatisfied
)
)
// Build the check arary
$checkArray = array("Data Date", "Agent IDENT", "Client IDENT", "Location IDENT", "Program IDENT");
$fileVerification = true;
$config_col = 1;
// Loop through the 50 available columns
while($config_col <= 50){
$csv_col = $config_col - 1;
print $csv_col . " ";
// Make sure something is in those columns
if($getConfiguration[0]['config_kpi_'.$config_col] != ''){
// There is, now lets query and get those names.
$getNamesQuery[] = "SELECT * FROM kpi_keys WHERE key_id=".$getConfiguration[0]['config_kpi_'.$config_col];
$getNamesResult = dbInsert($getNamesQuery);
// Compare the first 5 columns
if($csv_col < 5){
if($csvRead[0][$csv_col] == $checkArray[$csv_col]){
$output .= '<div class="messageGood"> - '.$csvRead[0][$csv_col].' column verified.</div>';
} else {
$output .= '<div class="messageBad"> - Column "'.$csvRead[0][$csv_col].'" did not match "'.$checkArray[$csv_col].'" in the current configuration.</div>';
$fileVerification = false;
}
} else {
// Now lets compare the customizable columns. We're going to do names and ID's to make sure.
print "Echo";
}
$getNamesQuery = null;
}
$config_col++;
}
// Now we check the information
print "<pre>";
print_r($getConfiguration[0]);
print_r($csvRead[0]);
print_r($getNamesResult);
print "</pre>";
Answer (Thanks Wrikken)
// Loop through the 50 available columns
while($config_col <= 50){
$csv_col = $config_col - 1;
$partOne = '';
$partTwo = '';
// Make sure something is in those columns
// Compare the first 5 columns
if($csv_col < 5){
if($csvRead[0][$csv_col] == $checkArray[$csv_col]){
$partOne .= '<div class="messageGood"> - '.$csvRead[0][$csv_col].' column verified.</div>';
} else {
$partOne .= '<div class="messageBad"> - Column "'.$csvRead[0][$csv_col].'" did not match "'.$checkArray[$csv_col].'" in the current configuration.</div>';
$fileVerification = false;
}
}
if($getConfiguration[0]['config_kpi_'.$config_col] != ''){
print $csv_col . " ";
// There is, now lets query and get those names.
$getNamesQuery[] = "SELECT * FROM kpi_keys WHERE key_id=".$getConfiguration[0]['config_kpi_'.$config_col];
$getNamesResult = dbInsert($getNamesQuery);
// Now lets compare the customizable columns. We're going to do names and ID's to make sure.
$partTwo = "Comparison";
$getNamesQuery = null;
}
$config_col++;
}
$output .= $partOne . $partTwo;
while($csv_col < 5){
if($csvRead[0][$csv_col] == $checkArray[$csv_col]){
$output .= '<div class="messageGood"> - '.$csvRead[0][$csv_col].' column verified.</div>';
if only runs one time,if you want to concatenate use while, it will run..until the end.

Categories