I have created this code:
header("Content-Type: application/json");
$method = $_SERVER['REQUEST_METHOD'];
$request = explode("/", substr(#$_SERVER['PATH_INFO'], 1));
switch ($method)
{
case 'PUT':
break;
case 'POST':
do_something_with_post($request);
break;
case 'GET':
do_something_with_get($request);
break;
case 'DELETE':
do_something_with_delete($request);
break;
default:
handle_error($request);
break;
}
Now suppose that I execute this command:
curl -X GET http://localhost/api/method/1
so in the switch is fired the GET case, how I can call the function method and pass the parameter 1?
how I should configure the code on the switch? Someone could help me to figure out?
Here's a simplified way to route request paths to classes. This example assumes your base path is /app and you have a sub-folder called /classes. The class name and file name must match for this to work.
Example request:
curl -X POST http://localhost/api/user/123
Example route:
File....: /app/classes/api/User.php
Class...: new User()
Action..: postAction( $arg1 = 123 )
...
// default route
$base = rtrim( str_replace( '\\', '/', __DIR__.'/app' ), '/' );
$area = 'api'; // area (/api, /test, etc.)
$class = 'home'; // class name (Home.php -> new Home(), etc.)
// parse request
$verb = strtolower( #$_SERVER['REQUEST_METHOD'] );
$path = parse_url( #$_SERVER['REQUEST_URI'], PHP_URL_PATH );
$args = explode( '/', trim( $path, '/' ) );
// extract area/class from request path
if( count( $args ) )
{
$area = array_shift( $args );
}
if( count( $args ) )
{
$class = array_shift( $args );
}
// finalize class name and file path
$class = str_replace( ' ', '', ucwords( str_replace( '-', ' ', $class ) ) );
$file = $base .'/classes/'. $area .'/'. $class.'.php';
$output = null;
// load/execute class
if( is_file( $file ) )
{
include_once( $file );
if( class_exists( $class ) )
{
$callable = [ new $class(), $verb.'Action' ];
if( is_callable( $callable ) )
{
$output = call_user_func_array( $callable, $args );
}
}
}
// send response output...
if( is_null( $output ) === false )
{
// ...
}
else
{
// handle error
}
exit;
You'll want to parse the URI:
$pieces = explode('?', $_SERVER['REQUEST_URI']);
$endpoint = $pieces[0];
$endpoint_parts = explode('/', $endpoint);
$api_method = $endpoint_parts[2];
$param = $endpoint_parts[3];
Then you can invoke method from your URL with 1 like this:
$api_method($param);
Related
When I installed WooCommerce on a WordPress page I got the chance to manage a little while ago, I started getting these errors whenever I go to a subpage:
Warning: preg_match() [function.preg-match]: Compilation failed: nothing to ?repeat at offset 1 in /var/www/watertours.dk/public_html/wp-includes/class-wp.php on line 222
Warning: preg_match() [function.preg-match]: Compilation failed: nothing to repeat at offset 1 in /var/www/watertours.dk/public_html/wp-includes/class-wp.php on line 223"
It even shows up in the dashboard occasionally.
I have found this guide which I have already tried several times:
step 0: if possible, backup your WP installation folder.
step 1: temporary disable all the plugins (important step)
step 2: in WordPress admin dashboard, go to Settings -> Permalinks
step 3: remember or note down somewhere what you have in the custom permalinks field: http://awesomescreenshot.com/0534epzk0c 96
step 4: temporary enable (switch to) the default permalink: http://awesomescreenshot.com/0f74epyi15 79 Click Save Changes button.
step 5: verify the website is working now (not everything, because the plugins are disabled, but the preg_match error should be gone)
step 6: switch back to the custom permalinks setting you had at step 3
step 7: enable back all the plugins
The error should be gone."
It works for a little while (two minutes or so) and then those two errors start popping up again.
I am thinking of just remaking the WordPress site from the ground up since it is quite a mess anyway. But if anyone has a solution, I would be more than grateful. :)
EDIT:
* Parse request to find correct WordPress query.
*
* Sets up the query variables based on the request. There are also many
* filters and actions that can be used to further manipulate the result.
*
* #since 2.0.0
*
* #global WP_Rewrite $wp_rewrite
*
* #param array|string $extra_query_vars Set the extra query variables.
*/
public function parse_request( $extra_query_vars = '' ) {
global $wp_rewrite;
/**
* Filters whether to parse the request.
*
* #since 3.5.0
*
* #param bool $bool Whether or not to parse the request. Default true.
* #param WP $this Current WordPress environment instance.
* #param array|string $extra_query_vars Extra passed query variables.
*/
if ( ! apply_filters( 'do_parse_request', true, $this, $extra_query_vars ) ) {
return;
}
$this->query_vars = array();
$post_type_query_vars = array();
if ( is_array( $extra_query_vars ) ) {
$this->extra_query_vars = & $extra_query_vars;
} elseif ( ! empty( $extra_query_vars ) ) {
parse_str( $extra_query_vars, $this->extra_query_vars );
}
// Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
// Fetch the rewrite rules.
$rewrite = $wp_rewrite->wp_rewrite_rules();
if ( ! empty( $rewrite ) ) {
// If we match a rewrite rule, this will be cleared.
$error = '404';
$this->did_permalink = true;
$pathinfo = isset( $_SERVER['PATH_INFO'] ) ? $_SERVER['PATH_INFO'] : '';
list( $pathinfo ) = explode( '?', $pathinfo );
$pathinfo = str_replace( '%', '%25', $pathinfo );
list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] );
$self = $_SERVER['PHP_SELF'];
$home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' );
$home_path_regex = sprintf( '|^%s|i', preg_quote( $home_path, '|' ) );
// Trim path info from the end and the leading home path from the
// front. For path info requests, this leaves us with the requesting
// filename, if any. For 404 requests, this leaves us with the
// requested permalink.
$req_uri = str_replace( $pathinfo, '', $req_uri );
$req_uri = trim( $req_uri, '/' );
$req_uri = preg_replace( $home_path_regex, '', $req_uri );
$req_uri = trim( $req_uri, '/' );
$pathinfo = trim( $pathinfo, '/' );
$pathinfo = preg_replace( $home_path_regex, '', $pathinfo );
$pathinfo = trim( $pathinfo, '/' );
$self = trim( $self, '/' );
$self = preg_replace( $home_path_regex, '', $self );
$self = trim( $self, '/' );
// The requested permalink is in $pathinfo for path info requests and
// $req_uri for other requests.
if ( ! empty( $pathinfo ) && ! preg_match( '|^.*' . $wp_rewrite->index . '$|', $pathinfo ) ) {
$requested_path = $pathinfo;
} else {
// If the request uri is the index, blank it out so that we don't try to match it against a rule.
if ( $req_uri == $wp_rewrite->index ) {
$req_uri = '';
}
$requested_path = $req_uri;
}
$requested_file = $req_uri;
$this->request = $requested_path;
// Look for matches.
$request_match = $requested_path;
if ( empty( $request_match ) ) {
// An empty request could only match against ^$ regex
if ( isset( $rewrite['$'] ) ) {
$this->matched_rule = '$';
$query = $rewrite['$'];
$matches = array( '' );
}
} else {
foreach ( (array) $rewrite as $match => $query ) {
// If the requested file is the anchor of the match, prepend it to the path info.
if ( ! empty( $requested_file ) && strpos( $match, $requested_file ) === 0 && $requested_file != $requested_path ) {
$request_match = $requested_file . '/' . $requested_path;
}
if ( preg_match( "#^$match#", $request_match, $matches ) || // Line 222
preg_match( "#^$match#", urldecode( $request_match ), $matches ) ) { // Line 223
if ( $wp_rewrite->use_verbose_page_rules && preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch ) ) {
// This is a verbose page match, let's check to be sure about it.
$page = get_page_by_path( $matches[ $varmatch[1] ] );
if ( ! $page ) {
continue;
}
$post_status_obj = get_post_status_object( $page->post_status );
if ( ! $post_status_obj->public && ! $post_status_obj->protected
&& ! $post_status_obj->private && $post_status_obj->exclude_from_search ) {
continue;
}
}
// Got a match.
$this->matched_rule = $match;
break;
}
}
}
if ( isset( $this->matched_rule ) ) {
// Trim the query of everything up to the '?'.
$query = preg_replace( '!^.+\?!', '', $query );
// Substitute the substring matches into the query.
$query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );
$this->matched_query = $query;
// Parse the query.
parse_str( $query, $perma_query_vars );
// If we're processing a 404 request, clear the error var since we found something.
if ( '404' == $error ) {
unset( $error, $_GET['error'] );
}
}
// If req_uri is empty or if it is a request for ourself, unset error.
if ( empty( $requested_path ) || $requested_file == $self || strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) {
unset( $error, $_GET['error'] );
if ( isset( $perma_query_vars ) && strpos( $_SERVER['PHP_SELF'], 'wp-admin/' ) !== false ) {
unset( $perma_query_vars );
}
$this->did_permalink = false;
}
}```
I've recently become the maintainer of a Wordpress site (I'm completely new to wordpress) and I'm having some difficulty determining where a redirect is specified.
I've checked the .htaccess file, and there's nothing specified in there. As far as I can tell, the rewrite rules aren't the cause.
I've tried deleting the page being redirected from and re-creating it, and the redirect still occurs.
My question is: where can you specify a redirect? I've run out of ideas of where to look.
one of my client want to custom url like
https://www.qsleap.com/gmat/resources as you know in wordpress evry request is catch by index.php . request filter catches the request and
call the page .
Read this code it may give you any idea.
function permalinks_customizer_request_before($query ){
$uri=$_SERVER['REQUEST_URI'];
$match= preg_match('/(gmat|gre|sat|lsat|cat)(\/resources\/tags\/)
(.*)\/(articles|videos|concept-notes|qna)/', $uri,$matches);
//$match=
preg_match('/(gmat|gre|sat|lsat|cat)/\resources/\tags/stanford-
gsb/\articles|videos|concept-notes)/?$', $uri,$matches);
if($match){
$url = parse_url( get_bloginfo( 'url' ) );
$url = isset( $url['path']) ? $url['path'] : '';
$request = ltrim( substr( $_SERVER['REQUEST_URI'], strlen( $url ) ), '/' );
$request = ( ( $pos = strpos( $request, '?' ) ) ? substr( $request, 0, $pos ) : $request );
if ( ! $request )
return $query;
$original_url="?page_name=tags&exam=".$matches[1]."&post_tag=".$matches[3]."&post_type=".$matches[4];
if ( $original_url !== null ) {
$original_url = str_replace('//', '/', $original_url);
if ( ( $pos = strpos( $_SERVER['REQUEST_URI'], '?' ) ) !== false ) {
$queryVars = substr( $_SERVER['REQUEST_URI'], $pos + 1 );
$original_url .= ( strpos( $original_url, '?' ) === false ? '?' : '&') . $queryVars;
}
$oldRequestUri = $_SERVER['REQUEST_URI'];
$oldQueryString = $_SERVER['QUERY_STRING'];
$_SERVER['REQUEST_URI'] = '/' . ltrim( $original_url, '/' );
$_SERVER['QUERY_STRING'] = ( ( $pos = strpos( $original_url, '?' ) ) !== false ? substr( $original_url, $pos + 1 ) : '' );
parse_str( $_SERVER['QUERY_STRING'], $queryArray );
$oldValues = array();
global $wp;
$wp->parse_request();
$query = $wp->query_vars;
if ( is_array( $queryArray ) ) {
foreach ( $queryArray as $key => $value ) {
$oldValues[$key] = $_REQUEST[$key];
$_REQUEST[$key] = $_GET[$key] = $value;
$query[$key]=$value;
}
}
$_SERVER['REQUEST_URI'] ='';
$_SERVER['QUERY_STRING']='';
}
}
return $query;
}
add_filter( 'request','permalinks_customizer_request_before',0);
function wp_url_rewrite_templates() {
if (get_query_var( 'page_name' ) && get_query_var( 'page_name'
)=='tags') {
add_filter( 'template_include', function() {
$template= dirname( __FILE__ ) . '/page-tags.php';
return $template;
});
}
}
add_action( 'template_redirect', 'wp_url_rewrite_templates' ,4 );
I think the easiest way for you to remove the redirects will be with this plugin.
https://redirection.me/
After you install it and activate it. From the Wordpress Admin
Tools > Redirection
You'll see a list of redirects, and add/remove any.
Problem it's in sub directories, i have many sub directories and sub sub directories, i need check them all, Maybe someone know how to help .
My code:
$mainFodlers = array_diff(scandir(self::PROJECT_DIRECTORY, 1), array('..', '.','__todo.txt'));
foreach ($mainFodlers as $mainFodler) {
if (is_dir(self::PROJECT_DIRECTORY . '/' . $mainFodler)) {
$subFolders = array_diff(scandir(self::PROJECT_DIRECTORY . '/' . $mainFodler, 1), array('..', '.','__todo.txt', 'share_scripts.phtml'));
} else {
$extension = $this->getExtension($subFolder);
if ($extension == 'phtml') {
$file = $subFolder;
$fileContent = file_get_contents(self::PROJECT_DIRECTORY . '/views/' . $file, true);
}
}
}
Because I cannot really determine the end result of your code it is hard to answer effectively but to solve the problem of nested folders you might wish to consider a recursiveIterator type approach. The following code should give a good starting point for you - it takes a directory $dir and will iterate through it and it's children.
/* Start directory */
$dir='c:/temp2';
/* Files & Folders to exclude */
$exclusions=array(
'oem_no_drivermax.inf',
'smwdm.sys',
'file_x',
'folder_x'
);
$dirItr = new RecursiveDirectoryIterator( $dir );
$filterItr = new DirFileFilter( $dirItr, $exclusions, $dir, 'all' );
$recItr = new RecursiveIteratorIterator( $filterItr, RecursiveIteratorIterator::SELF_FIRST );
foreach( $recItr as $filepath => $info ){
$key = realpath( $info->getPathName() );
$filename = $info->getFileName();
echo 'Key = '.$key . ' ~ Filename = '.$filename.'<br />';
}
$dirItr = $filterItr = $recItr = null;
Supporting class
class DirFileFilter extends RecursiveFilterIterator{
protected $exclude;
protected $root;
protected $mode;
public function __construct( $iterator, $exclude=array(), $root, $mode='all' ){
parent::__construct( $iterator );
$this->exclude = $exclude;
$this->root = $root;
$this->mode = $mode;
}
public function accept(){
$folpath=rtrim( str_replace( $this->root, '', $this->getPathname() ), '\\' );
$ext=strtolower( pathinfo( $this->getFilename(), PATHINFO_EXTENSION ) );
switch( $this->mode ){
case 'all':
return !( in_array( $this->getFilename(), $this->exclude ) or in_array( $folpath, $this->exclude ) or in_array( $ext, $this->exclude ) );
case 'files':
return ( $this->isFile() && ( !in_array( $this->getFilename(), $this->exclude ) or !in_array( $ext, $this->exclude ) ) );
break;
case 'dirs':
case 'folders':
return ( $this->isDir() && !( in_array( $this->getFilename(), $this->exclude ) ) && !in_array( $folpath, $this->exclude ) );
break;
default:
echo 'config error: ' . $this->mode .' is not recognised';
break;
}
return false;
}
public function getChildren(){
return new self( $this->getInnerIterator()->getChildren(), $this->exclude, $this->root, $this->mode );
}
}
I have an url that contain the word "&key".
The "&key" word can be at the beginning or at the end of our url.
Ex1= http://xxxxx.com?c1=xxx&c2=xxx&c3=xxx&key=xxx&c4=xxx&f1=xxx
Ex2= http://xxxxx.com?c1=xxx&key=xxx&c2=xxx&c3=xxx&c4=xxx&f1=xxx
What I would like to get is all the time the url with the Key element and it's value.
R1: http://xxxxx.com?c1=xxx&c2=xxx&c3=xxx&key=xxx
R2: http://xxxxx.com?c1=xxx&key=xxx
Here is what I have done:
$lp_sp_ad_publisher = "http://xxxxx.com?c1=xxx&c2=xxx&c3=xxx&key=xxxc4=xxxf1=xxx";
$lp_sp_ad_publisher_cut_link = explode("&", $lp_sp_ad_publisher_cut[1]); // tab
$lp_sp_ad_publisher_cut_link_final = $lp_sp_ad_publisher_cut_link[0]; // http://xxxxx.com?c1=xxx
$counter = 1;
// finding &key inside $lp_sp_ad_publisher_cut_link_final
while ((strpos($lp_sp_ad_publisher_cut_link_final, '&key')) !== false);
{
$lp_sp_ad_publisher_cut_link_final .= $lp_sp_ad_publisher_cut_link[$counter];
echo 'counter: ' . $counter . ' link: ' . $lp_sp_ad_publisher_cut_link_final . '<br/>';
$counter++;
}
I'm only looping once all the time. I guess the while loop isn't refreshing with the inside new value. Any solution?
EDIT: Sorry, I misunderstood the question.
This is tricky because the url key and value can be anything, so it might be safer to breakdown the URL using a combination of parse_url() and parse_str(), then put the url back together leaving off the part you don't want. Something like this:
function cut_url( $url='', $key='' )
{
$output = '';
$parts = parse_url( $url );
$query = array();
if( isset( $parts['scheme'] ) )
{
$output .= $parts['scheme'].'://';
}
if( isset( $parts['host'] ) )
{
$output .= $parts['host'];
}
if( isset( $parts['path'] ) )
{
$output .= $parts['path'];
}
if( isset( $parts['query'] ) )
{
$output .= '?';
parse_str( $parts['query'], $query );
}
foreach( $query as $qkey => $qvalue )
{
$output .= $qkey.'='.$qvalue.'&';
if( $qkey == $key ) break;
}
return rtrim( $output, '&' );
}
Usage:
$input = 'https://www.xxxxx.com/test/path/index.php?c1=xxx&c2=xxx&key=xxx&c3=xxx&c4=xxx&f1=xxx';
$output = cut_url( $input, 'key' );
Output:
https://www.xxxxx.com/test/path/index.php?c1=xxx&c2=xxx&key=xxx
If the intention is to always ensure that the parameter key and it's associated value appear at the end of the string, how about something like:
$tmp=array();$key='';
$parts=explode( '&', parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY ) );
foreach( $parts as $pair ) {
list( $param,$value )=explode( '=',$pair );
if( $param=='key' )$key=$pair;
else $tmp[]=$pair;
}
$query = implode( '&', array( implode( '&', $tmp ), $key ) );
echo $query;
or,
parse_str( $_SERVER['QUERY_STRING'], $pieces );
foreach( $pieces as $param => $value ){
if( $param=='key' ) $key=$param.'='.$value;
else $tmp[]=$param.'='.$value;
}
$query = implode( '&', array( implode( '&', $tmp ), $key ) );
update
I'm puzzled that you were "not getting the good result"!
consider the url:
https://localhost/index.php?sort=0&dir=false&tax=23&cost=99&aardvark=creepy&key=banana&tree=large&ac=dc&limit=1000#569f945674935
The above would output:
sort=0&dir=false&tax=23&cost=99&aardvark=creepy&tree=large&ac=dc&limit=1000&key=banana
so the key=banana gets placed last using either method above.
I have been using the following script to create sitemaps for my clients websites. The issue is it does not work for every site. I have found that many if not all the sites hosted on godaddy do not spider. If anyone can see an error in my script or know what is causing the fault I would greatly appreciate the help.
Thanks in advance
set_time_limit(0);
class spider_man
{
var $url;
var $limit;
var $cache;
var $crawled;
var $banned_ext;
var $domain;
function spider_man( $url, $banned_ext, $limit ){
$this->domain = $url;
$this->url = 'http://'.$url ;
$this->banned_ext = $banned_ext ;
$this->limit = $limit ;
if( !fopen( $this->url, "r") ) return false;
else $this->_spider($this->url);
}
function _spider( $url ){
$this->cache = #file_get_contents( urldecode( $url ) );
if( !$this->cache ) return false;
$this->crawled[] = urldecode( $url ) ;
preg_match_all( "#href=\"(https?://[&=a-zA-Z0-9-_./]+)\"#si", $this->cache, $links );
if ( $links ) :
foreach ( $links[1] as $hyperlink ){
if(strpos($hyperlink,$this->domain)===false){ break; }
else{
$this->limit--;
if( ! $this->limit ) return;
if( $this->is_valid_ext( trim( $hyperlink ) ) and !$this->is_crawled( $hyperlink ) ) :
$this->crawled[] = $hyperlink;
echo "Crawling $hyperlink<br />\n";
unset( $this->cache );
$this->_spider( $hyperlink );
endif;
}
}
endif;
}
function is_valid_ext( $url ){
foreach( $this->banned_ext as $ext ){
if( $ext == substr( $url, strlen($url) - strlen( $ext ) ) ) return false;
}
return true;
}
function is_crawled( $url ){
return in_array( $url, $this->crawled );
}
}
$banned_ext = array(".dtd",".css",".xml",".js",".gif",".jpg",".jpeg",".bmp",".ico",".rss",".pdf",".png",".psd",".aspx",".jsp",".srf",".cgi",".exe",".cfm");
$spider = new spider_man( 'domain.com', $banned_ext, 100 );
print_r( $spider->crawled );
When you access a site using fopen() of file_get_contents() you don't send AGENT or REFERRER or other header information. It's blatently obvious that this is an automated script.
You need to look at sending context with your fopen (check the docs and read the context section) or, better still, using CURL. This allows you to set the agent and referrer headers to simulate a browser.