I used to include files between sites routinely, until my webhost banned the practice. Now it appears that a recent PHP upgrade also tightened the screws, as I'm getting a "no suitable wrapper could be found" error - and I'm working with LOCAL sites.
Let's start with a website # www.gx.com and a subdomain at subdomain.mysite.com. However, they display locally as two separate websites - mysite.com and subdomain.com.
A page on subdomain.com features the following include request:
require_once($GX_URL."/2b/inc/D/Shared/Body/Bottom/Footer.php
$GX_URL displays as http[://]gx locally and http[://]gx.com online.
How can I modify this include so it works in both situations? I can use the following switch to hold two separate includes, one for online use and the other for local use:
switch(PHP_OS)
{
case 'Linux':
break;
default:
break;
}
I just figured the answer to my first question; I simply mapped out the entire path to the file in the other website on my computer:
/Applications/MAMP/htdocs/gx/2b/inc/D/Shared/Body/Bottom/Footer.php
So I guess I need to do something similar to include a file from my main domain. However, I'll leave this question open in case anyone has a more elegant solution.
I have more you can try one.
Try download html and include to your php page :).
Http Request or CURL request
Use Allow_url_include, example: http://wiki.dreamhost.com/Allow_url_include
Use Object download: http://php.net/manual/de/function.ob-start.php
Example::
1. Curl Download html string
function curl_get($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, $this->CURL_UA);
curl_setopt($ch, CURLOPT_REFERER, $this->YT_BASE_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec ($ch);
curl_close ($ch);
return $contents;
}
2. Http send request width file_get_contents
function sendRequest($url, $data = array())
{
$data = http_build_query($data);
$context_options = array('http' => array('method' => 'POST',
'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
'content' => $data)
);
$context = stream_context_create($context_options);
$result = file_get_contents($url, false, $context);
return $result;
}
3 Object : http://php.net/manual/de/function.ob-start.php
Related
I have a small php script: domain1.com/script1.php
//my database connections, check functions and values, then, load:
$variable1 = 'value1';
$variable2 = 'value2';
if ($variable1 > 5) {
$variable3 = 'ok';
} else {
$variable3 = 'no';
}
And I need to load the variables of this script on several other sites of mine (different domains, servers and ips), so I can control all of them from a single file, for example:
domain2.com/site.php
domain3.com/site.php
domain4.com/site.php
And the "site.php" file needs to call the variable that is in script1.php (but I didn't want to have to copy this file in each of the 25 domains and edit each of them every day):
site.php:
echo $variable1 . $variable2 . $variable3; //loaded by script.php another domain
I don't know if the best and easiest way is to pass this: via API, Cookie, Javascript, JSON or try to load it as an include even from php, authorizing the domain in php.ini. I can't use get variables in the url, like ?variable1=abc.
My area would be php (but not very advanced either), and the rest I am extremely layman, so depending on the solution, I will have to hire a developer, but I wanted to understand what to ask the developer, or maybe the cheapest solution for this (even if not the best), as they are non-profit sites.
Thank you.
If privacy is not a concern, then file_get_contents('https://example.com/file.php') will do. Have the information itself be passed as JSON text it's the industry standard.
If need to protect the information, make a POST request (using cURL or guzzle library) with some password assuming you're using https protocol.
On example.com server:
$param = $_REQUEST("param");
$result = [
'param' => $param,
'hello' => "world"
];
echo json_encode($data);
On client server:
$content = file_get_contents('https://example.com/file.php');
$result = json_decode($content, true);
print_r ($result);
For completeness, here's a POST request:
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/file.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
$result = json_decode($server_output , true);
I'm using file_get_contents() to get a PHP file which I use as a template to create a PDF.
I need to pass some POST values to it, in order to fill the template and get the produced HTML back into a PHP variable. Then use it with mPDF.
This works perfectly on MY server (a VPS using PHP 5.6.24)...
Now, at the point where I'm installing the fully tested script on the client's live site (PHP 5.6.29),
I get this error:
PHP Warning: file_get_contents(http://www.example.com/wp-content/calculator/pdf_page1.php): failed to open stream: HTTP request failed! HTTP/1.1 406 Not Acceptable
So I guess this can be fixed in php.ini or some config file.
I can ask (I WANT TO!!) my client to contact his host to fix it...
But since I know that hosters are generally not inclined to change server configs...
I would like to know exactly what to change in which file to allow the code below to work.
For my personnal knowledge... Obviously.
But also to make it look "easy" for the hoster (and my client!!) to change it efficiently. ;)
I'm pretty sure this is just one PHP config param with a strange name...
<?php
$baseAddr = "http://www.example.com/wp-content/calculator/";
// ====================================================
// CLEAR OLD PDFs
$now = date("U");
$delayToKeepPDFs = 60*60*2; // 2 hours in seconds.
if ($handle = opendir('.')) {
while (false !== ($entry = readdir($handle))) {
if(substr($entry,-4)==".pdf"){
$fileTime = filemtime($entry); // Returns unix timestamp;
if($fileTime+$delayToKeepPDFs<$now){
unlink($entry); // Delete file
}
}
}
closedir($handle);
}
// ====================================================
// Random file number
$random = rand(100, 999);
$page1 = $_POST['page1']; // Here are the values, sent via ajax, to fill the template.
$page2 = $_POST['page2'];
// Instantiate mpdf
require_once __DIR__ . '/vendor/autoload.php';
$mpdf = new mPDF( __DIR__ . '/vendor/mpdf/mpdf/tmp');
// GET PDF templates from external PHP
// ==============================================================
// REF: http://stackoverflow.com/a/2445332/2159528
// ==============================================================
$postdata = http_build_query(
array(
"page1" => $page1,
"page2" => $page2
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
// ==============================================================
$STYLE .= file_get_contents("smolov.css", false, $context);
$PAGE_1 .= file_get_contents($baseAddr . "pdf_page1.php", false, $context);
$PAGE_2 .= file_get_contents($baseAddr . "pdf_page2.php", false, $context);
$mpdf->AddPage('P');
// Write style.
$mpdf->WriteHTML($STYLE,1);
// Write page 1.
$mpdf->WriteHTML($PAGE_1,2);
$mpdf->AddPage('P');
// Write page 1.
$mpdf->WriteHTML($PAGE_2,2);
// Create the pdf on server
$file = "training-" . $random . ".pdf";
$mpdf->Output(__DIR__ . "/" . $file,"F");
// Send filename to ajax success.
echo $file;
?>
Just to avoid the "What have you tried so far?" comments:
I searched those keywords in many combinaisons, but didn't found the setting that would need to be changed:
php
php.ini
request
header
content-type
application
HTTP
file_get_contents
HTTP/1.1 406 Not Acceptable
Maaaaany thanks to #Rasclatt for the priceless help! Here is a working cURL code, as an alternative to file_get_contents() (I do not quite understand it yet... But proven functional!):
function curl_get_contents($url, $fields, $fields_url_enc){
# Start curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
# Required to get data back
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# Notes that request is sending a POST
curl_setopt($ch,CURLOPT_POST, count($fields));
# Send the post data
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_url_enc);
# Send a fake user agent to simulate a browser hit
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56');
# Set the endpoint
curl_setopt($ch, CURLOPT_URL, $url);
# Execute the call and get the data back from the hit
$data = curl_exec($ch);
# Close the connection
curl_close($ch);
# Send back data
return $data;
}
# Store post data
$fields = array(
'page1' => $_POST['page1'],
'page2' => $_POST['page2']
);
# Create query string as noted in the curl manual
$fields_url_enc = http_build_query($fields);
# Request to page 1, sending post data
$PAGE_1 .= curl_get_contents($baseAddr . "pdf_page1.php", $fields, $fields_url_enc);
# Request to page 2, sending post data
$PAGE_2 .= curl_get_contents($baseAddr . "pdf_page2.php", $fields, $fields_url_enc);
I have a website, that uses WP Super Cache plugin. I need to recycle cache once a day and then I need to call 5 posts (URL adresses) so WP Super Cache put these posts into cache again (caching is quite time consuming so I'd like to have it precached before users come so they dont have to wait).
On my hosting I can use a CRON but only for 1 call/hour. And I need to call 5 different URL's at once.
Is it possible to do that? Maybe create one HTML page with these 5 posts in iframe? Will something like that work?
Edit: Shell is not available, so I have to use PHP scripting.
The easiest way to do it in PHP is to use file_get_contents() (fopen() also works), if the HTTP stream wrapper is enabled on your server:
<?php
$postUrls = array(
'http://my.site.here/post1',
'http://my.site.here/post2',
'http://my.site.here/post3',
'http://my.site.here/post4',
'http://my.site.here/post5',
);
foreach ($postUrls as $url) {
// Get the post as an user will do it
$text = file_get_contents();
// Here you can check if the request was successful
// For example, use strpos() or regex to find a piece of text you expect
// to find in the post
// Replace 'copyright bla, bla, bla' with a piece of text you display
// in the footer of your site
if (strpos($text, 'copyright bla, bla, bla') === FALSE) {
echo('Retrieval of '.$url." failed.\n");
}
}
If file_get_contents() fails to open the URLs on your server (some ISP restrict this behaviour) you can try to use curl:
function curl_get_contents($url)
{
$ch = curl_init($url);
curl_setopt_array($ch, array(
CURLOPT_CONNECTTIMEOUT => 30, // timeout in seconds
CURLOPT_RETURNTRANSFER => TRUE, // tell curl to return the page content instead of just TRUE/FALSE
));
$text = curl_exec($ch);
curl_close($ch);
return $text;
}
Then use the function curl_get_contents() listed above instead of file_get_contents().
An example using PHP without building a cURL request.
Using PHP's shell exec, you can have an extremely light function like so :
$siteList = array("http://url1", "http://url2", "http://url3", "http://url4", "http://url5");
foreach ($siteList as &$site) {
$request = shell_exec('wget '.$site);
}
Now of course this is not the most concise answer and not always a good solution also, if you actually want anything from the response you will have to work with it a different way to cURLbut its a low impact option.
Thanks to Arkascha tip I created a PHP page that I call from CRON. This page contains simple function using cURL:
function cache_it($Url){
if (!function_exists('curl_init')){
die('No cURL, sorry!');
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $Url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 50); //higher timeout needed for cache to load
curl_exec($ch); //dont need it as output, otherwise $output = curl_exec($ch);
curl_close($ch);
}
cache_it('http://www.mywebsite.com/url1');
cache_it('http://www.mywebsite.com/url2');
cache_it('http://www.mywebsite.com/url3');
cache_it('http://www.mywebsite.com/url4');
I am trying to implement a simple foldergrid php client. I am using the simple php client from the foldergrid api documentation. The client code that I got from the api documentation is:
class FolderGridClient {
protected $_cookieFileLocation = './cookie.txt';
public $_webpage;
public $_status;
public $_location;
const SERVER_HOST = 'https://secure.foldergrid.com';
public function authenticate($username,$password, $domain){
$params = array("domain"=>$domain,"username"=>$username,"password"=>$password);
$this->createCurl(self::SERVER_HOST."/login",$params);
}
public function createDomain($adminemail,$adminpassword, $domainname, $adminfname, $adminlname){
$json = json_encode( array('invite'=>true, 'admin' => array('email'=>$adminemail,'password'=>$adminpassword,'firstname'=>$adminfname,'lastname'=>$adminlname) ) );
$this->createCurl(self::SERVER_HOST."/domain/".$domainname,$json,true);
}
public function uploadFile($file,$name,$parentDuid) {
$fh = fopen($file, "rb");
if($fh) {
$json = json_encode( array('parentDuid'=>$parentDuid, 'name' => $name, 'parts' => 1) );
$this->createCurl(self::SERVER_HOST."/file/provision",$json,true);
if($this->_location){
$headers = array(
'fg-eap: false',
'fg-md5:'.md5_file($file),
'Content-Type: binary/octet-stream'
);
$curl = curl_init();
curl_setopt($curl,CURLOPT_PUT,true);
curl_setopt($curl, CURLOPT_HEADER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_URL, $this->_location);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_INFILE, $fh);
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($file));
curl_setopt( $curl, CURLOPT_VERBOSE, true );
$this->_webpage = curl_exec($curl);
$this->_status = curl_getinfo($curl,CURLINFO_HTTP_CODE);
fclose($fh);
curl_close($curl);
}
}else{
echo "File not found: $file \n";
}
}
public function fetchFolder($pathOrDuid){
$this->createCurl(self::SERVER_HOST."/folder/$pathOrDuid");
return $this->_webpage;
}
public function fetchFile($fileid){
$this->createCurl(self::SERVER_HOST."/file/$fileid");
return $this->_webpage;
}
public function createCurl($url,$postFields = null, $put = false)
{
$s = curl_init();
curl_setopt($s, CURLOPT_VERBOSE, true);
curl_setopt($s,CURLOPT_URL,$url);
curl_setopt($s,CURLOPT_RETURNTRANSFER,true);
curl_setopt($s, CURLOPT_HEADER, TRUE);
curl_setopt($s,CURLOPT_FOLLOWLOCATION,false);
curl_setopt($s,CURLOPT_COOKIEJAR,$this->_cookieFileLocation);
curl_setopt($s,CURLOPT_COOKIEFILE,$this->_cookieFileLocation);
if($postFields)
{
curl_setopt($s,CURLOPT_POST,true);
if($put) {
curl_setopt($s, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($postFields)));
curl_setopt($s,CURLOPT_CUSTOMREQUEST, "PUT");
}else{
curl_setopt($s, CURLOPT_HTTPHEADER, array('Expect:'));
}
curl_setopt($s,CURLOPT_POSTFIELDS,$postFields);
}
$this->_webpage = curl_exec($s);
$this->_status = curl_getinfo($s,CURLINFO_HTTP_CODE);
preg_match_all('/^Location:(.*)$/mi', $this->_webpage, $matches);
$this->_location = !empty($matches[1]) ? trim($matches[1][0]) : null;
curl_close($s);
}
}
Using this client, I was able to successfully upload a file to my folder grid root folder. Now I have created a test folder under the root, and I am trying to use the API to get the duid of the folder. I used the following code:
$uname='myuname';
$pwd='mypwd';
$domain='mydomain';
$rootDUID='duidOFRootFolder';
$client = new FolderGridClient;
$client->authenticate( $uname,$pwd,$domain);
if($client->_status < 400){
echo "fetchFolder: " . $client->fetchFolder($domain.'/TestNewFolder') . "<BR>";
}
TestNewFolder is the name of the folder I created using the foldergrid javascript reference client at https://mydomain.foldergrid.com/show/*.html
The root foldername is the same as my domain name, which i think is standard for foldergrid.
However, when I run that code, I always get a folder not found response. I have tried various different permutations of the folder path as an input to the fetchFolder function with no success. so two questions:
1. how should I use the fetchFolder function in the php simple client to get the folder info - specifically the duid.
2. Does anyone have an addition to the php simple client to create a sub folder, once I have discovered the duid of the target folder?
THANKS
When you create a new folder programmatically using the FolderGrid API you assign the immutable DUID which uniquely identifies that folder. One easy method to determine the DUID for any existing folder is to simply open the FolderGrid Web App and right click the folder to choose "Show Info".
To determine an unknown DUID programmatically using API calls, you simply traverse the folder path from a higher folder with a known DUID using calls to Show Folder Details which display the DUIDs of all subfolders. For example, you would execute a GET /folder/DUID on your root folder which will return (among other things) a json array of the names and DUIDs of all the subfolders of your root folder - including TestNewFolder
One useful shortcut is mentioned in the API docs for Show Folder Details which is that you can substitute asterisk '*' for DUID in that call as a shorthand reference to the root folder.
The sample PHP client code uses the name "pathOrDuid" for the parameter to fetchFolder but that's misleading because the call to retrieve a folder's details by path is a distinct call as documented here.
So following Simmerman's suggestions, here is some php code that I used to get the duid of a sub folder if I know the parent folders duid (like '*' for the root folder). I have added the following function to the php simple client that foldergrid provided in their documentation:
public function getSubFolderDuid($parentDuid,$folderName) {
$fetchParent = $this->fetchFolder($parentDuid);
$parentJsonMatch = array();
preg_match("/\{.*\}/",$fetchParent,&$parentJsonMatch);
$returnArray=true;
$parentJsonArray = json_decode($parentJsonMatch[0],$returnArray);
$subFolders = $parentJsonArray['folders'];
foreach($subFolders as $folderData) {
if ($folderData['name'] == $folderName) return $folderData['duid'];
}
return '';
}
obviously there is plenty of room to add error handling to this function in case the parent folder is not returned. This function is assuming the parent folder exists and is returned as json data.
Here is the code I used to call the function:
if($client->_status < 400){
$parentDuid = '*';
$folderName = 'TestNewFolder';
$folderDuid = $client->getSubFolderDuid($parentDuid,$folderName);
echo "$folderName: $folderDuid<br>";
}
With these building blocks I can now build code to traverse the directory tree or find a specific folder duid at an arbitrary depth in the tree.
Thanks for the pointing me in the right direction Simmerman
I tried to post to wordpress blog from extrnal php code , all of my files are in the same directory, public_html.
this is my code:
function wpPostXMLRPC1($title,$body,$rpcurl,$username,$password,$category,$keywords='',$encoding='UTF-8') {
$title = htmlentities($title,ENT_NOQUOTES,$encoding);
$keywords = htmlentities($keywords,ENT_NOQUOTES,$encoding);
$content = array(
'title'=>$title,
'description'=>$body,
'mt_allow_comments'=>0, // 1 to allow comments
'mt_allow_pings'=>0, // 1 to allow trackbacks
'post_type'=>'post',
'mt_keywords'=>$keywords,
'categories'=>array($category)
);
$params = array(0,$username,$password,$content,true);
$request = xmlrpc_encode_request('metaWeblog.newPost',$params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);
return $results;
}
but its wrong, the error is
Fatal error: Call to undefined function xmlrpc_encode_request()
i can post to my wordpress blog with microsoft word(publish->blogPost), so Help me
PHP's xmlrpc extension seems to be not enabled on your server.
Wordpress using http://scripts.incutio.com/xmlrpc/ as xmlrpc server, you don't need xmlrpc extension to post to your wp. Just follow the instruction http://scripts.incutio.com/xmlrpc/advanced-client-construction.php.
But if you want to post on another way, such as posting by email you can follow this tutorial codex.wordpress.org/Post_to_your_blog_using_email
I struggled with the same. I found a similar problem somewhere else on the net and tweaked to to fit Wordpress. Mind you Wordpress install (wordpress.org), not the blog hosting service at wordpress.com. This should be working provided you have curl and xmlwriter enabled:
<?php
class atompub
{
//public $parae = '';
function __construct($one, $two, $three, $four)
{
$this->author=$one;
$this->title=$two;
$this->categories=$three;
$this->body=$four;
}
function create_post()
{
$xmlwriter = new XMLWriter();
$xmlwriter->openMemory();
$xmlwriter->startDocument("1.0", "UTF-8");
$xmlwriter->startElement('entry');
$xmlwriter->writeAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$xmlwriter->startElement('author');
$xmlwriter->writeElement('name', $this->author);
$xmlwriter->endElement();
$xmlwriter->writeElement('title', $this->title);
$xmlwriter->startElement('content');
$xmlwriter->writeAttribute('type', 'html');
$xmlwriter->text($this->body);
$xmlwriter->endElement();
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', $this->categories);
$xmlwriter->endElement();
$xmlwriter->endElement();
$xmlwriter->endDocument();
return $xmlwriter->outputMemory();
}
function __destruct()
{
}
}
$target = "<URL til your WordPress installation>/wp-app.php/posts";
// Note that the directory "posts" are used for posting (POST method)
// "service" is used to pull info via the GET method (not shown here)
$user = "XXX"; // Substitue XXX with your WordPress username
$passwd = "YYY"; // Substitue XXX with your WordPress password
$author='Your Name';
$title='The title of your choice for your new entry';
$array_of_categories='Category';
$body='This is the main body. All the text goes in here';
$xml_post = new atompub($author,$title,$array_of_categories,$body);
$post = $xml_post->create_post();
$headers = array("Content-Type: application/atom+xml ");
$handle = curl_init($target);
$curlopt_array = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERPWD => $user.':'.$passwd,
CURLOPT_FOLLOWLOCATION => true,
CURLINFO_HEADER_OUT => true);
curl_setopt_array($handle, $curlopt_array);
$result = curl_exec($handle);
//var_dump($result);
$header_sent=curl_getinfo($handle);
//var_dump($header_sent);
if ($result === false) {
print "Got " . curl_errno($handle) . " : " . curl_error($handle) . "\n";
curl_close ($handle);
return;
}
$response_http_code = curl_getinfo ($handle, CURLINFO_HTTP_CODE);
if ($response_http_code != 201) {
print("HTTP status code: $response_http_code \n");
curl_close($handle);
return;
}
curl_close($handle);
?>
This should work directly, but you need to change the strings indicated (Blog URL, username, password, author, etc...). Beware that the login in insecure. This is only for demonstrating the functionality. You may also want to change the response code handling (which isn't mine, it came along with the original example which this is based upon).
On success Wordpress returns XML to you with details of the post event.
Fatal error: Call to undefined function xmlrpc_encode_request()
some times this error appear because xmlrpc extension is disabled.
execute phpinfo() to see if xmlrpc module displays or not.
If not, you need to enable it from php.ini by removing the semicolon, like
;extension=php_xmlrpc.dll to extension=php_xmlrpc.dll
and then restart Apache