parsing SEO friendly url without htaccess or mode_rewrite - php

Can anyone suggest a method in php or a function for parsingSEO friendly urls that doesn't involve htaccess or mod_rewrite? Examples would be awesome.
http://url.org/file.php/test/test2#3
This returns: Array ( scheme] => http [host] => url.org [path] => /file.php/test/test2 [fragment] => 3 ) /file.php/test/test2
How would I separate out the /file.php/test/test2 section? I guess test and test2 would be arguments.
EDIT:
#Martijn - I did figure out what your suggested before getting the notification about your answer. Thanks btw. Is this considered an ok method?
$url = 'http://url.org/file.php/arg1/arg2#3';
$test = parse_url($url);
echo "host: $test[host] <br>";
echo "path: $test[path] <br>";
echo "frag: $test[fragment] <br>";
$path = explode("/", trim($test[path]));
echo "1: $path[1] <br>";
echo "2: $path[2] <br>";
echo "3: $path[3] <br>";
echo "4: $path[4] <br>";

You can use explode to get the parts from your array:
$path = trim($array['path'], "/"); // trim the path of slashes
$path = explode("/", $path);
unset($path[0]); // the first one is the file, the others are sections of the url
If you really want to make it zerobased again, add this as last line:
$patch = array_values($path);
In response to your edit:
You want to make this as flexible as you can, so no fixed coding based on a max of 5 items. Although you probably will never exceed that, just don't pin yourself to it, just overhead you dont need.
If you have a pages system like this:
id parent name url
1 -1 Foo foo
2 1 Bar, child of Foo bar-child-of-foo
Make a recursive function. Pass the array to a function which takes the first section to find a root item
SELECT * FROM pages WHERE parent=-1 AND url=$path[0]
That query will return an id, use that in the parent column with the next value of the array. Unset each found value of the $path array. In the end, you will have an array with the remaining parts.
To sketch an example:
function GetFullPath(&$path, $parent=-1){
$path = "/"; // start with a slash
// Make the query for childs of this item
$result = mysqli_query($conn, "SELECT * FROM pages WHERE parent=".$parent." AND url=".current($path)." LIMIT 1");
// If any rows exists, append more of the url via recursiveness:
if($result->num_rows!==0){
// Remove the first part so if we go one deeper we start with the next value
$path = array_slice($patch,1); // remove first value
$fetch = $result->fetch_assoc();
// Use the fetched value to go deeper, find a child with the current item as parent
$path.= GetFullPath($path, $fetch['parent']);
}
// Return the result. if nothing is found at all, the result will be "/", probs home
return $path;
}
echo GetFullPath($path); // I pass it by reference, any alterations in the function happen to the variable outside the scope aswell
This is a draft, I did not test this, but you get the idea im trying to sketch. You can use the same method to get the ID of the page you are at. Just keep passing the variable back up again c
One of these days im getting the hang of recursiveness ^^.
Edit again: Oops, that turned out to be quite some code.

Related

Get info from API/URL

I have the URL https://android.rediptv2.com/ch.php?usercode=5266113827&pid=1&mac=02:00:00:00:00:00&sn=&customer=GOOGLE&lang=eng&cs=amlogic&check=3177926680
which outputs statistics.
For example:
[{"id":"2972","name":"MBC 1","link":"http://46.105.112.116/?watch=TR/mbc1-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/MBC1En.ae-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc1.png"},{"id":"1858","name":"MBC 2","link":"http://46.105.112.116/?watch=TN/mbc2-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/MBC2En.ae-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc2.png"},{"id":"1859","name":"MBC 3","link":"http://46.105.112.116/?watch=TN/mbc3-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc3.png"}]
I want to get the value of link count.
Can anyone help?
I tried to do:
<?php
$content = file_get_contents("https://android.rediptv2.com/ch.php?usercode=5266113827&pid=1&mac=02:00:00:00:00:00&sn=&customer=GOOGLE&lang=eng&cs=amlogic&check=3177926680");
$result = json_decode($content);
print_r( $result->link );
?>
But it didn't work.
Put the JSON in an editor and you'll see that it's an array and not an object with the link attribute. This is why you cannot access it directly. You have to loop over the items and then you'll be able to access the link property of one of the items. If you need to access the link by id, as you asked 4 months later, then just create a dictionnary in an array indexed by id and containing just the interesting data you need.
PHP code:
<?php
// The result of the request:
$content = <<<END_OF_STRING
[{"id":"2972","name":"MBC 1","link":"http://46.105.112.116/?watch=TR/mbc1-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/MBC1En.ae-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc1.png"},{"id":"1858","name":"MBC 2","link":"http://46.105.112.116/?watch=TN/mbc2-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/MBC2En.ae-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc2.png"},{"id":"1859","name":"MBC 3","link":"http://46.105.112.116/?watch=TN/mbc3-ar&token=RED_cexVeBNZ8mioQnjmGiYNEg==,1643770076.5266113827&t=1&s=2&p=1&c=BR&r=1351&lb=1","epg":"https://epg.cdnrdn.com/-20220201.xml","dvr":"disabled","language":"Arabic","category":"TOP 100","logo":"http://files.rednetcontent.com/chlogo/mbc3.png"}]
END_OF_STRING;
$items = json_decode($content);
echo '$items = ' . var_export($items, true) . "\n\n";
// Create a dictionnary to store each link accessible by id.
$links_by_id = [];
// Loop over all items:
foreach ($items as $i => $item) {
// Show how to access the current link.
echo "Link $i = $item->link\n";
// Fill the dictionary.
$links_by_id[(int)$item->id] = $item->link;
}
// To access the first one:
echo "\nFirst link = " . $items[0]->link . "\n";
// Example of access by id:
// The id seems to be a string. It could probably be "1895" or "zhb34" or whatever.
// (If they are only numbers, we could convert the string to an integer).
$id = "1859";
echo "\nAccess with id $id = " . $links_by_id[$id] . "\n";
Test it here: https://onlinephp.io/c/e8ab9
Another important point: You are getting a 403 Forbidden error on the URL you provided. So typically, you will not obtain the JSON you wanted.
As I explained in the comment below, I think that you will not be able to access this page without having a fresh URL with valid query parameters and/or cookies. I imagine you obtained this URL from somewhere and it is no longer valid. This is why you'll probably need to use cURL to visit the website with a session to obtain the fresh URL to the JSON API. Use Google to find some examples of PHP scraping/crawling with session handling. You'll see that depending on the website it can get rather tricky, especially if some JavaScript comes into the game.

Filter a php array to only elements that have a matching value to $name in $data

I have a php script getting all folders in a posts folder and making them into a list.
I have a $postinfo_str variable assigned to a json file for each folder which I am using to store post date and category/tag info etc in.
I also have a $pagetitle variable assigned to a title.php include file for each folder. So say I am on a "June 2018" archive page, the text in that file will be "June 2018". If I am on say a "Tutorials" category page, that will be the text in the title.php.
In the json file, I have:
{
"Arraysortdate": "YYYYMMDD",
"Month": "Month YYYY",
"Category": ["cat1", "cat2", "etc"]
}
I am ordering the array newest to oldest using krsort with Arraysortdate as key.
How do I filter the array using $pagetitle as input, finding if there is a match in $postinfo_str, and if there isn't, remove that folder from the array?
All I can seem to find regarding array sorting is where the info in the $pageinfo_str is basically the array and so by that, the $title is the input and the output is the matching text from the $postinfo_str, whereas I want the output to be the folders that only have the matching text in the $postinfo_str to what the input ($pagetitle) is.
Here is my code I have.. Keep in mind this is flat file, I do not want a database to achieve this. See comments if you want an explaination.
<?php
$BASE_PATH = '/path/to/public_html';
// initial array containing the dirs
$dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);
// new array with date as key
$dirinfo_arr = [];
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
}
// now we sort the new array
krsort($dirinfo_arr);
foreach($dirinfo_arr as $key=>$dir) {
$dirpath = $dir['dir'];
$dirpath = str_replace('/path/to/public_html/', '', $dirpath);
?>
<!--HTML HERE SUCH AS--!>
TEXT <br>
<?php
};
?>
I have difficulties following your problem description. Your code example is slightly confusing. It appears to load the same global includes/title.php for each directory. Meaning, the value of $pagetitle should be the same every iteration. If this is intended, you should probably move that line right outside the loop. If the file contains actual php code, you should probably use
$pagetitle = include 'includes/title.php';
or something similar. If it doesn't, you should probably name it title.txt. If it is not one global file, you should probably add the path to the file_get_contents/include as well. (However, why wouldn't you just add the title in the json struct?)
I'm under the assumption that this happened by accident when trying to provide a minimal code example (?) ... In any case, my answer won't be the perfect answer, but it hopefully can be adapted once understood ;o)
If you only want elements in your array, that fulfill certain properties, you have essentially two choices:
don't put those element in (mostly your code)
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
// ------------ NEW --------------
$filtercat = 'cat1';
if(!in_array($filtercat, $dirinfo['Category'])) {
continue;
}
// -------------------------------
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
array_filter the array afterwards, by providing a anonymous function
// ----- before cycling through $dirinfo_arr for output
$filtercat = 'cat1';
$filterfunc = function($dirinfo) use ($filtercat) {
return in_array($filtercat, $dirinfo['Category']));
}
$dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
you should read up about anonymous functions and how you provide local vars to them, to ease the pain. maybe your use case is bettersuited for array_reduce, which is similar, except you can determine the output of your "filter".
$new = array_filter($array, $func), is just a fancy way of writing:
$new = [];
foreach($array as $key => $value) {
if($func($value)) {
$new[$key] = $value;
}
}
update 1
in my code samples, you could replace in_array($filtercat, $dirinfo['Category']) with in_array($pagetitle, $dirinfo) - if you want to match on anything that's in the json-struct (base level) - or with ($pagetitle == $dirinfo['Month']) if you just want to match the month.
update 2
I understand, that you're probably just starting with php or even programming, so the concept of some "huge database" may be frightening. But tbh, the filesystem is - from a certain point of view - a database as well. However, it usually is quite slow in comparison, it also doesn't provide many features.
In the long run, I would strongly suggest using a database. If you don't like the idea of putting your data in "some database server", use sqlite. However, there is a learning curve involved, if you never had to deal with databases before. In the long run it will be time worth spending, because it simplifys so many things.

Dynamically created directory returns "Array" 1 in 1000 times

I'm fixing up some old code that is supposed to create a directory for a customer based on the customer's last name. 999 out of 1000 times it works as expected but every now and then I get an "Unable to create base directory" error message and the debug shows me that the $file_directory in that case is simply "Array" instead of something like "\\network\path\order_data\1234567890_Smith".
Could anyone explain how this code could work the vast majority of the time but still consistently fail about .1% of instances? Or is it something other than the code? Thanks!
Note: I did not originally write this code but am tring to leave it as close to the original as possible
Edit I had a typo in my previous code but I think tliokos and Fluinc had a very good point but just wanted to fix my mistake
Code:
<?php
$file_directory = build_directory($customer, $UID);
if(!is_dir($file_directory)){ //Check to make sure it does not already exist
if(!mkdir($file_directory)){
mail("debug#example.com","Unable to create base directory","$file_directory");
}
}
function build_directory($customer, $UID){
if($customer->related_orders){
$related = explode(",", $customer->related_orders);
foreach($related as $r_UID){
$rel_order = get_order($r_UID); //fetches order object
if((isset($rel_order->file_directory) && $rel_order->file_directory != "")){
return $rel_order->file_directory;
}
}
}
//Here is where I made my correction
$paths = array('\\\\network\\path');
$base = $paths[0];
//Test if directory is already assigned
if(is_dir($base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\")){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
if($base){
return $base . "\\order_data\\".$UID."_".str_replace(" ","_",$customer->last_name)."\\";
}
}
?>
Change $base = array('\\network\path');
To $base = '\\network\path';
I think the problem is in the build_directory() function and more specifically after the first if.
So if the customer has no related orders, you are trying to concatenate an Array with a string and the result is like
Array\order_data\....
Try o change
$base = array('\\network\path');
to
$base = '\\network\path';
So the problem ended up being framework/user related.
We discovered that if the user refreshed the page during the directory creation it would create the same directory twice which our framework would save as an array of identical paths.

How to retrieve script name from full absolute URL using PHP?

I'm able to retrieve the full URL like: http://www-click08-co-uk/wonga.php
and I need to retrieve the script name "wonga" from it.
The url will be changing depending on what page the user is on and I will always need the word or phrase after the / and not including the .php, in the example above I would like to create a variable with the value of this being wonga
This is the code I currently have, where "argos" is, is where the database is searched and responds with the information I need, this is where the vaiable would be used
<?php
//-----------------------------------------------------
// Include files and set Classes
//-----------------------------------------------------
require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/common.php";
$db = new dbConnection();
$directorydata = new directorydata();
$phoneDirectory = new phoneDirectory();
$conn = $db->pdoConnect();
// Load the directorydata row via the row ID - 543 is "best buy"
//$directorydata->get($db, 543);
// Load the directorydata row via the url alias field
$directorydata->get($db, "Argos");
// Phone number isn't formatted coming out the DB
$formattedPhoneNumber = $phoneDirectory->formatPhoneNumber($directorydata->Number1);
?>
Just because you didn't provide any code, I provide you a way to solve this on your own:
$url = "http://www-click08-co-uk/wonga.php";
// SEARCH and replace
// FIRST_FUNCTION => google => php trailing name component of path
// SECOND_FUNCTION => google => php explode a string by string
// THIRD_FUNCTION => google => php pop first element of array
$urlParts = SECOND_FUNCTION( ".", FIRST_FUNCTION( $url ) );
echo THIRD_FUNCTION( $urlParts );
OUTPUT:
wonga
An example use of parse_url could be:
$url = 'http://www-click08-co-uk/wonga.php?page=74';
$route = parse_url($url, PHP_URL_PATH);
$routeTokens = explode('/', $route);
$scriptName = array_pop($routeTokens);
echo $scriptName;
which in this case outputs wonga.php.
Just note that this is a very rare task that you would have to take care of yourself. So instead of parse_url you might look at the bigger picture here and start looking for some good MVC framework.

Random Link PHP

EDITED
I'm trying to setup a random link at the bottom of all my pages. I'm using the code below, but want to make it so the current page is not included in the random rotation of links.
Example:
I need code to randomly select and display ONE of these links. The exception being, IF article1.php is currently being viewed, I want it to be excluded from the random selection. That way only links to OTHER articles are seen on any given article.
http://mysite.com/article1.php
http://mysite.com/article2.php
http://mysite.com/article3.php
I would use array_rand with something like:
<?php
$links = array(array('url' => 'http://google.com', 'name'=>'google'),
array('url' => 'http://hotmail.com', 'name' => 'hotmail'),
array('url' => 'http://hawkee.com', 'name' => 'Hawkee'));
$num = array_rand($links);
$item = $links[$num];
printf('%s', $item['url'], $item['name'], $item['name']);
?>
Where links makes it easier to build an array. Nevertheless, I think we miss some details about how you grab your links.
What is the mean of "current page"? because the simplest way to do, is just not add the page to the array.
And the use of array_rand avoids confusion with size of array and so.
Edit: I suppose you use a database, so you may have an sql request like:
SELECT myfieldset FROM `articles` WHERE id = 'theid';
So you know the id of the current article. Now you just have to build an array with some other articles with a query like:
SELECT id FROM `articles` WHERE id NOT IN ('theid') ORDER BY RAND LIMIT 5
And build the candidate array with those results.
Each time you randomly choose a URL to display, pop it off of the array and store it in a temporary variable. Then, on the next rotation make your selection and THEN push the previously used URL back into the array.
$lastUrl = trim(file_get_contents('last_url.txt'));
while($lastUrl == ($randUrl = $urls[rand(0, count($urls) - 1)])){}
file_put_contents('last_url.txt', $randUrl);
// ...
echo $randUrl;
Ensures that on each page load, you will not receive the previous URL. This, however is just an example. You would want to incorporate file locking, exception handling (perhaps) or an entirely different storage medium (DB, etc.)
To ensure the URL is not the same as the current, this should do the trick:
// get current URL
$currentUrl = 'http://' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
// randomize URLs until you get one that doesn't match the current
while($currentUrl == ($randUrl = $urls[rand(0, count($urls) - 1)])){ }
echo $randUrl;
Google "PHP get current URL", and you'll get considerably more detailed ways to capture the current URL. For example, conditions on whether or not you're use HTTPS, to append an 's' to the protocol component.
try the codes below :
$links = array(
'http://mysite.com/article1.php',
'http://mysite.com/article2.php',
'http://mysite.com/article3.php',
'http://mysite.com/article4.php',
'http://mysite.com/article5.php'
);
$currentPage = basename($_SERVER['SCRIPT_NAME']);
$count = 0;
$currentIndex = NULL;
foreach($links as $link) {
if(strpos($link, "/".$currentPage)>-1) $currentIndex = $count;
$count++;
}
if($currentIndex) {
do{
$random = mt_rand(0, sizeof($links) - 1);
} while($random==$currentIndex);
} else {
$random = mt_rand(0, sizeof($links) - 1);
}
$random_link = $links[$random];

Categories