I work on Laravel framework for a short time, after finishing the website, I willing to encode it using Ioncube - but I face the problem where Ioncube can't translate the blade template engine code to PHP code before encoding and output the code as HTML normal text.
Laravel's blade template files are not real PHP code, therefore the ionCube Encoder cannot encode them properly; however, the Encoder also offers file encryption which might help in your case, but it does require a bit of a setup:
In Laravel, modify the module that reads in the Blade template files, replacing file_get_contents(<blade template files>) with ioncube_read_file(<blade template_files>).
In my Laravel 4 installation, it seems like the file responsible for loading and compiling Blade Templates can be found in vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php, line 62: $contents = $this->compileString($this->files->get($path));.
Here, $this->files->get($path) is 'just' a file_get_contents($path) with some error handling - you may find this function in bootstrap/compiled.php. However, you should be able to replace the line in BladeCompiler.php with:
$contents = $this->compileString(ioncube_read_file($path));
or (if you used a passphrase):
$passphrase = "<my passphrase>";
$contents = $this->compileString(ioncube_read_file($path, $is_encrypted, $passphrase));
Please do note that you might want to make sure that the passphrase is secure within the file. You can find more information on these functions in the User Guide on page 54.
To get ioncube_read_file working, you will need to encode the modified module. Furthermore, encode the rest of your application with the exception of your Blade template files.
Encrypt (not encode!) your Blade template files, typically ending in .blade.php, and - if you use a passphrase - make sure it matches the one used for ioncube_read_file.
Please also keep in mind that this will generate standard PHP files from your encrypted ones, since the file is compiled and written back to the cache as plain text. If you want to change that it might be worth looking into the User Guide, p. 54 and override / extend the appropriate methods bootstrap/compiled.php such as get and put to detect if a file is encrypted, and to write an encrypted file if needed.
I should also mention, as this question is regularly asked on the ionCube HelpDesk: Despite all the encoding and encrypting, the HTML and JavaScript code will be displayed raw for all clients to see. I only mention this because it is a lot of effort to protect your Template files, which do consist in most cases mostly of HTML code. It does make any modification really hard (such as logo removal), but such things may also be achieved with some custom CSS.
After coming across this issue I believe this answer will be the simple and easy way to solve it. With this methode you won't have to edit framework files every after update.
Create your own new Service Provider to replace ViewServiceProvider. Name it IonCubeCompilerServiceProvider
Create new Class to extend BladeCompiler. Name it IonCubeBladeCompiler
Finally, swap the Illuminate\View\ViewServiceProvider::class out of the config/app.php providers array, and replace it with your own ViewServiceProvider.
namespace App\Providers;
use App\Libraries\IonCubeBladeCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\ViewServiceProvider;
class IonCubeCompilerServiceProvider extends ViewServiceProvider
{
public function registerBladeEngine($resolver)
{
$this->app->singleton('blade.compiler', function () {
return new IonCubeBladeCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}
Second file.
namespace App\Libraries;
use Illuminate\View\Compilers\BladeCompiler;
class IonCubeBladeCompiler extends BladeCompiler
{
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (! is_null($this->cachePath)) {
if(function_exists('ioncube_read_file')){
//This is what I'm adding.
$contents = $this->compileString(ioncube_read_file($this->getPath()));
}else{
//This is the original line.
$contents = $this->compileString($this->files->get($this->getPath()));
}
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}
}
}
For more details you can check the following two links
https://laracasts.com/discuss/channels/laravel/extend-the-compile-function-on-bladecompilerphp
and
http://blog.ioncube.com/2016/12/19/ioncube-encoding-laravel-project-controllers-models-templates/
I created class:
<?php
namespace App\Classes\Compiler;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\View\Compilers\Compiler;
use Illuminate\View\Compilers\CompilerInterface;
class CustomCompiler extends Compiler implements CompilerInterface
{
/**
* All of the registered extensions.
*
* #var array
*/
protected $extensions = [];
/**
* All custom "directive" handlers.
*
* This was implemented as a more usable "extend" in 5.1.
*
* #var array
*/
protected $customDirectives = [];
/**
* The file currently being compiled.
*
* #var string
*/
protected $path;
/**
* All of the available compiler functions.
*
* #var array
*/
protected $compilers = [
'Extensions',
'Statements',
'Comments',
'Echos',
];
/**
* Array of opening and closing tags for raw echos.
*
* #var array
*/
protected $rawTags = ['{!!', '!!}'];
/**
* Array of opening and closing tags for regular echos.
*
* #var array
*/
protected $contentTags = ['{{', '}}'];
/**
* Array of opening and closing tags for escaped echos.
*
* #var array
*/
protected $escapedTags = ['{{{', '}}}'];
/**
* The "regular" / legacy echo string format.
*
* #var string
*/
protected $echoFormat = 'e(%s)';
/**
* Array of footer lines to be added to template.
*
* #var array
*/
protected $footer = [];
/**
* Placeholder to temporary mark the position of verbatim blocks.
*
* #var string
*/
protected $verbatimPlaceholder = '#__verbatim__#';
/**
* Array to temporary store the verbatim blocks found in the template.
*
* #var array
*/
protected $verbatimBlocks = [];
/**
* Counter to keep track of nested forelse statements.
*
* #var int
*/
protected $forelseCounter = 0;
/**
* Compile the view at the given path.
*
* #param string $path
* #return void
*/
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (! is_null($this->cachePath)) {
if (function_exists('ioncube_read_file')) {
$contents = $this->compileString(ioncube_read_file($this->getPath()));
}
else {
$contents = $this->compileString($this->files->get($this->getPath()));
}
$this->files->put($this->getCompiledPath($this->getPath()), $contents);
}
}
/**
* Get the path currently being compiled.
*
* #return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set the path currently being compiled.
*
* #param string $path
* #return void
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Compile the given Blade template contents.
*
* #param string $value
* #return string
*/
public function compileString($value)
{
$result = '';
if (strpos($value, '#verbatim') !== false) {
$value = $this->storeVerbatimBlocks($value);
}
$this->footer = [];
// Here we will loop through all of the tokens returned by the Zend lexer and
// parse each one into the corresponding valid PHP. We will then have this
// template as the correctly rendered PHP that can be rendered natively.
foreach (token_get_all($value) as $token) {
$result .= is_array($token) ? $this->parseToken($token) : $token;
}
if (! empty($this->verbatimBlocks)) {
$result = $this->restoreVerbatimBlocks($result);
}
// If there are any footer lines that need to get added to a template we will
// add them here at the end of the template. This gets used mainly for the
// template inheritance via the extends keyword that should be appended.
if (count($this->footer) > 0) {
$result = ltrim($result, PHP_EOL)
.PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
}
return $result;
}
/**
* Store the verbatim blocks and replace them with a temporary placeholder.
*
* #param string $value
* #return string
*/
protected function storeVerbatimBlocks($value)
{
return preg_replace_callback('/(?<!#)#verbatim(.*?)#endverbatim/s', function ($matches) {
$this->verbatimBlocks[] = $matches[1];
return $this->verbatimPlaceholder;
}, $value);
}
/**
* Replace the raw placeholders with the original code stored in the raw blocks.
*
* #param string $result
* #return string
*/
protected function restoreVerbatimBlocks($result)
{
$result = preg_replace_callback('/'.preg_quote($this->verbatimPlaceholder).'/', function () {
return array_shift($this->verbatimBlocks);
}, $result);
$this->verbatimBlocks = [];
return $result;
}
/**
* Parse the tokens from the template.
*
* #param array $token
* #return string
*/
protected function parseToken($token)
{
list($id, $content) = $token;
if ($id == T_INLINE_HTML) {
foreach ($this->compilers as $type) {
$content = $this->{"compile{$type}"}($content);
}
}
return $content;
}
/**
* Execute the user defined extensions.
*
* #param string $value
* #return string
*/
protected function compileExtensions($value)
{
foreach ($this->extensions as $compiler) {
$value = call_user_func($compiler, $value, $this);
}
return $value;
}
/**
* Compile Blade comments into valid PHP.
*
* #param string $value
* #return string
*/
protected function compileComments($value)
{
$pattern = sprintf('/%s--(.*?)--%s/s', $this->contentTags[0], $this->contentTags[1]);
return preg_replace($pattern, '', $value);
}
/**
* Compile Blade echos into valid PHP.
*
* #param string $value
* #return string
*/
protected function compileEchos($value)
{
foreach ($this->getEchoMethods() as $method => $length) {
$value = $this->$method($value);
}
return $value;
}
/**
* Get the echo methods in the proper order for compilation.
*
* #return array
*/
protected function getEchoMethods()
{
$methods = [
'compileRawEchos' => strlen(stripcslashes($this->rawTags[0])),
'compileEscapedEchos' => strlen(stripcslashes($this->escapedTags[0])),
'compileRegularEchos' => strlen(stripcslashes($this->contentTags[0])),
];
uksort($methods, function ($method1, $method2) use ($methods) {
// Ensure the longest tags are processed first
if ($methods[$method1] > $methods[$method2]) {
return -1;
}
if ($methods[$method1] < $methods[$method2]) {
return 1;
}
// Otherwise give preference to raw tags (assuming they've overridden)
if ($method1 === 'compileRawEchos') {
return -1;
}
if ($method2 === 'compileRawEchos') {
return 1;
}
if ($method1 === 'compileEscapedEchos') {
return -1;
}
if ($method2 === 'compileEscapedEchos') {
return 1;
}
});
return $methods;
}
/**
* Compile Blade statements that start with "#".
*
* #param string $value
* #return mixed
*/
protected function compileStatements($value)
{
$callback = function ($match) {
if (Str::contains($match[1], '#')) {
$match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
} elseif (isset($this->customDirectives[$match[1]])) {
$match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));
} elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {
$match[0] = $this->$method(Arr::get($match, 3));
}
return isset($match[3]) ? $match[0] : $match[0].$match[2];
};
return preg_replace_callback('/\B#(#?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', $callback, $value);
}
/**
* Compile the "raw" echo statements.
*
* #param string $value
* #return string
*/
protected function compileRawEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$this->compileEchoDefaults($matches[2]).'; ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the "regular" echo statements.
*
* #param string $value
* #return string
*/
protected function compileRegularEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
$wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
return $matches[1] ? substr($matches[0], 1) : '<?php echo '.$wrapped.'; ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the escaped echo statements.
*
* #param string $value
* #return string
*/
protected function compileEscapedEchos($value)
{
$pattern = sprintf('/(#)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
$callback = function ($matches) {
$whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
return $matches[1] ? $matches[0] : '<?php echo e('.$this->compileEchoDefaults($matches[2]).'); ?>'.$whitespace;
};
return preg_replace_callback($pattern, $callback, $value);
}
/**
* Compile the default values for the echo statement.
*
* #param string $value
* #return string
*/
public function compileEchoDefaults($value)
{
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/s', 'isset($1) ? $1 : $2', $value);
}
/**
* Compile the each statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEach($expression)
{
return "<?php echo \$__env->renderEach{$expression}; ?>";
}
/**
* Compile the inject statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileInject($expression)
{
$segments = explode(',', preg_replace("/[\(\)\\\"\']/", '', $expression));
return '<?php $'.trim($segments[0])." = app('".trim($segments[1])."'); ?>";
}
/**
* Compile the yield statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileYield($expression)
{
return "<?php echo \$__env->yieldContent{$expression}; ?>";
}
/**
* Compile the show statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileShow($expression)
{
return '<?php echo $__env->yieldSection(); ?>';
}
/**
* Compile the section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileSection($expression)
{
return "<?php \$__env->startSection{$expression}; ?>";
}
/**
* Compile the append statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileAppend($expression)
{
return '<?php $__env->appendSection(); ?>';
}
/**
* Compile the end-section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndsection($expression)
{
return '<?php $__env->stopSection(); ?>';
}
/**
* Compile the stop statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileStop($expression)
{
return '<?php $__env->stopSection(); ?>';
}
/**
* Compile the overwrite statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileOverwrite($expression)
{
return '<?php $__env->stopSection(true); ?>';
}
/**
* Compile the unless statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileUnless($expression)
{
return "<?php if (! $expression): ?>";
}
/**
* Compile the end unless statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndunless($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the lang statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileLang($expression)
{
return "<?php echo app('translator')->get$expression; ?>";
}
/**
* Compile the choice statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileChoice($expression)
{
return "<?php echo app('translator')->choice$expression; ?>";
}
/**
* Compile the else statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElse($expression)
{
return '<?php else: ?>';
}
/**
* Compile the for statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileFor($expression)
{
return "<?php for{$expression}: ?>";
}
/**
* Compile the foreach statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileForeach($expression)
{
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getFirstLoop();';
return "<?php {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} ?>";
}
/**
* Compile the break statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileBreak($expression)
{
return $expression ? "<?php if{$expression} break; ?>" : '<?php break; ?>';
}
/**
* Compile the continue statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileContinue($expression)
{
return $expression ? "<?php if{$expression} continue; ?>" : '<?php continue; ?>';
}
/**
* Compile the forelse statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileForelse($expression)
{
$empty = '$__empty_'.++$this->forelseCounter;
preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
$iteratee = trim($matches[1]);
$iteration = trim($matches[2]);
$initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
$iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getFirstLoop();';
return "<?php {$empty} = true; {$initLoop} foreach(\$__currentLoopData as {$iteration}): {$iterateLoop} {$empty} = false; ?>";
}
/**
* Compile the can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileCan($expression)
{
return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
}
/**
* Compile the else-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElsecan($expression)
{
return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->check{$expression}): ?>";
}
/**
* Compile the cannot statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileCannot($expression)
{
return "<?php if (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
}
/**
* Compile the else-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElsecannot($expression)
{
return "<?php elseif (app('Illuminate\\Contracts\\Auth\\Access\\Gate')->denies{$expression}): ?>";
}
/**
* Compile the if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileIf($expression)
{
return "<?php if{$expression}: ?>";
}
/**
* Compile the else-if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileElseif($expression)
{
return "<?php elseif{$expression}: ?>";
}
/**
* Compile the forelse statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEmpty($expression)
{
$empty = '$__empty_'.$this->forelseCounter--;
return "<?php endforeach; \$__env->popLoop(); \$loop = \$__env->getFirstLoop(); if ({$empty}): ?>";
}
/**
* Compile the has section statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileHasSection($expression)
{
return "<?php if (! empty(trim(\$__env->yieldContent{$expression}))): ?>";
}
/**
* Compile the while statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileWhile($expression)
{
return "<?php while{$expression}: ?>";
}
/**
* Compile the end-while statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndwhile($expression)
{
return '<?php endwhile; ?>';
}
/**
* Compile the end-for statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndfor($expression)
{
return '<?php endfor; ?>';
}
/**
* Compile the end-for-each statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndforeach($expression)
{
return '<?php endforeach; $__env->popLoop(); $loop = $__env->getFirstLoop(); ?>';
}
/**
* Compile the end-can statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndcan($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-cannot statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndcannot($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-if statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndif($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the end-for-else statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndforelse($expression)
{
return '<?php endif; ?>';
}
/**
* Compile the raw PHP statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compilePhp($expression)
{
return $expression ? "<?php {$expression}; ?>" : '<?php ';
}
/**
* Compile end-php statement into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndphp($expression)
{
return ' ?>';
}
/**
* Compile the unset statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileUnset($expression)
{
return "<?php unset{$expression}; ?>";
}
/**
* Compile the extends statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileExtends($expression)
{
$expression = $this->stripParentheses($expression);
$data = "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
$this->footer[] = $data;
return '';
}
/**
* Compile the include statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileInclude($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the include statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileIncludeIf($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php if (\$__env->exists($expression)) echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
/**
* Compile the stack statements into the content.
*
* #param string $expression
* #return string
*/
protected function compileStack($expression)
{
return "<?php echo \$__env->yieldPushContent{$expression}; ?>";
}
/**
* Compile the push statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compilePush($expression)
{
return "<?php \$__env->startPush{$expression}; ?>";
}
/**
* Compile the endpush statements into valid PHP.
*
* #param string $expression
* #return string
*/
protected function compileEndpush($expression)
{
return '<?php $__env->stopPush(); ?>';
}
/**
* Strip the parentheses from the given expression.
*
* #param string $expression
* #return string
*/
public function stripParentheses($expression)
{
if (Str::startsWith($expression, '(')) {
$expression = substr($expression, 1, -1);
}
return $expression;
}
/**
* Get the extensions used by the compiler.
*
* #return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Register a custom Blade compiler.
*
* #param callable $compiler
* #return void
*/
public function extend(callable $compiler)
{
$this->extensions[] = $compiler;
}
/**
* Call the given directive with the given value.
*
* #param string $name
* #param string|null $value
* #return string
*/
protected function callCustomDirective($name, $value)
{
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
$value = Str::substr($value, 1, -1);
}
return call_user_func($this->customDirectives[$name], trim($value));
}
/**
* Register a handler for custom directives.
*
* #param string $name
* #param callable $handler
* #return void
*/
public function directive($name, callable $handler)
{
$this->customDirectives[$name] = $handler;
}
/**
* Get the list of custom directives.
*
* #return array
*/
public function getCustomDirectives()
{
return $this->customDirectives;
}
/**
* Gets the raw tags used by the compiler.
*
* #return array
*/
public function getRawTags()
{
return $this->rawTags;
}
/**
* Sets the raw tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #return void
*/
public function setRawTags($openTag, $closeTag)
{
$this->rawTags = [preg_quote($openTag), preg_quote($closeTag)];
}
/**
* Sets the content tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #param bool $escaped
* #return void
*/
public function setContentTags($openTag, $closeTag, $escaped = false)
{
$property = ($escaped === true) ? 'escapedTags' : 'contentTags';
$this->{$property} = [preg_quote($openTag), preg_quote($closeTag)];
}
/**
* Sets the escaped content tags used for the compiler.
*
* #param string $openTag
* #param string $closeTag
* #return void
*/
public function setEscapedContentTags($openTag, $closeTag)
{
$this->setContentTags($openTag, $closeTag, true);
}
/**
* Gets the content tags used for the compiler.
*
* #return string
*/
public function getContentTags()
{
return $this->getTags();
}
/**
* Gets the escaped content tags used for the compiler.
*
* #return string
*/
public function getEscapedContentTags()
{
return $this->getTags(true);
}
/**
* Gets the tags used for the compiler.
*
* #param bool $escaped
* #return array
*/
protected function getTags($escaped = false)
{
$tags = $escaped ? $this->escapedTags : $this->contentTags;
return array_map('stripcslashes', $tags);
}
/**
* Set the echo format to be used by the compiler.
*
* #param string $format
* #return void
*/
public function setEchoFormat($format)
{
$this->echoFormat = $format;
}
}
Then created provider
<?php
namespace App\Providers;
use App\Classes\Compiler\CustomCompiler;
use Illuminate\View\Engines\CompilerEngine;
use Illuminate\View\ViewServiceProvider as ViewProvider;
class ViewServiceProvider extends ViewProvider
{
public function registerBladeEngine($resolver)
{
$this->app->singleton('blade.compiler', function () {
return new CustomCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}
then replaced
Illuminate\View\ViewServiceProvider::class,
with my own
App\Providers\ViewServiceProvider::class,
in config/app.php.
Then put the .blade.php to the Non-PHP-encryption extensions.
I use obfuscation and generated key.
Blade templates work fine.
Related
This question already has answers here:
PHP parse/syntax errors; and how to solve them
(20 answers)
Closed 3 years ago.
I'm setting solarium in my codigniter web application. And create test query. It shows
A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by (output started at C:\wamp\www\solarium\application\vendor\solarium\solarium\src\Core\Client\Request.php:309)
Filename: core/Common.php
Line Number: 570
Backtrace:
And
A PHP Error was encountered
Severity: Parsing Error
Message: syntax error, unexpected ':', expecting ';' or '{'
Filename: Client/Request.php
Line Number: 309
Backtrace:
I enclose my file in below
<?php
namespace Solarium\Core\Client;
use Solarium\Component\RequestBuilder\RequestParamsInterface;
use Solarium\Component\RequestBuilder\RequestParamsTrait;
use Solarium\Core\Configurable;
use Solarium\Exception\RuntimeException;
/**
* Class for describing a request.
*/
class Request extends Configurable implements RequestParamsInterface
{
use RequestParamsTrait;
/**
* Request GET method.
*/
const METHOD_GET = 'GET';
/**
* Request POST method.
*/
const METHOD_POST = 'POST';
/**
* Request HEAD method.
*/
const METHOD_HEAD = 'HEAD';
/**
* Request DELETE method.
*/
const METHOD_DELETE = 'DELETE';
/**
* Request PUT method.
*/
const METHOD_PUT = 'PUT';
/**
* Default options.
*
* #var array
*/
protected $options = [
'method' => self::METHOD_GET,
];
/**
* Request headers.
*/
protected $headers = [];
/**
* Raw POST data.
*
* #var string
*/
protected $rawData;
/**
* Magic method enables a object to be transformed to a string.
*
* Get a summary showing significant variables in the object
* note: uri resource is decoded for readability
*
* #return string
*/
public function __toString()
{
$output = __CLASS__.'::__toString'."\n".'method: '.$this->getMethod()."\n".'header: '.print_r($this->getHeaders(), 1).'authentication: '.print_r($this->getAuthentication(), 1).'resource: '.$this->getUri()."\n".'resource urldecoded: '.urldecode($this->getUri())."\n".'raw data: '.$this->getRawData()."\n".'file upload: '.$this->getFileUpload()."\n";
return $output;
}
/**
* Set request handler.
*
* #param string $handler
*
* #return self Provides fluent interface
*/
public function setHandler($handler)
{
$this->setOption('handler', $handler);
return $this;
}
/**
* Get request handler.
*
* #return string
*/
public function getHandler()
{
return $this->getOption('handler');
}
/**
* Set request method.
*
* Use one of the constants as value
*
* #param string $method
*
* #return self Provides fluent interface
*/
public function setMethod($method)
{
$this->setOption('method', $method);
return $this;
}
/**
* Get request method.
*
* #return string
*/
public function getMethod()
{
return $this->getOption('method');
}
/**
* Get raw POST data.
*
* #return string
*/
public function getRawData()
{
return $this->rawData;
}
/**
* Set raw POST data.
*
* This string must be safely encoded.
*
* #param string $data
*
* #return self Provides fluent interface
*/
public function setRawData($data)
{
$this->rawData = $data;
return $this;
}
/**
* Get the file to upload via "multipart/form-data" POST request.
*
* #return string|null
*/
public function getFileUpload()
{
return $this->getOption('file');
}
/**
* Set the file to upload via "multipart/form-data" POST request.
*
*
* #param string $filename Name of file to upload
*
* #throws RuntimeException
*
* #return self
*/
public function setFileUpload($filename)
{
if (!is_file($filename) || !is_readable($filename)) {
throw new RuntimeException("Unable to read file '{$filename}' for upload");
}
$this->setOption('file', $filename);
return $this;
}
/**
* Get all request headers.
*
* #return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Set request headers.
*
* #param array $headers
*
* #return self Provides fluent interface
*/
public function setHeaders($headers)
{
$this->clearHeaders();
$this->addHeaders($headers);
return $this;
}
/**
* Add a request header.
*
* #param string|array $value
*
* #return self Provides fluent interface
*/
public function addHeader($value)
{
$this->headers[] = $value;
return $this;
}
/**
* Add multiple headers to the request.
*
* #param array $headers
*
* #return self Provides fluent interface
*/
public function addHeaders($headers)
{
foreach ($headers as $header) {
$this->addHeader($header);
}
return $this;
}
/**
* Clear all request headers.
*
* #return self Provides fluent interface
*/
public function clearHeaders()
{
$this->headers = [];
return $this;
}
/**
* Get an URI for this request.
*
* #return string
*/
public function getUri()
{
return $this->getHandler().'?'.$this->getQueryString();
}
/**
* Set HTTP basic auth settings.
*
* If one or both values are NULL authentication will be disabled
*
* #param string $username
* #param string $password
*
* #return self Provides fluent interface
*/
public function setAuthentication($username, $password)
{
$this->setOption('username', $username);
$this->setOption('password', $password);
return $this;
}
/**
* Get HTTP basic auth settings.
*
* #return array
*/
public function getAuthentication()
{
return [
'username' => $this->getOption('username'),
'password' => $this->getOption('password'),
];
}
/**
* Execute a request outside of the core context in the global solr context.
*
* #param bool $isServerRequest
*/
public function setIsServerRequest($isServerRequest = false)
{
$this->setOption('isserverrequest', $isServerRequest);
}
/**
* Indicates if a request is core independent and could be executed outside a core context.
* By default a Request is not core independent and must be executed in the context of a core.
*
* #return bool
*/
public function getIsServerRequest(): bool
{
return $this->getOption('isserverrequest') ?? false;
}
/**
* Initialization hook.
*/
protected function init()
{
foreach ($this->options as $name => $value) {
switch ($name) {
case 'rawdata':
$this->setRawData($value);
break;
case 'file':
$this->setFileUpload($value);
break;
case 'param':
$this->setParams($value);
break;
case 'header':
$this->setHeaders($value);
break;
case 'authentication':
if (isset($value['username']) && isset($value['password'])) {
$this->setAuthentication($value['username'], $value['password']);
}
}
}
}
/**
* #return string
*/
public function getHash()
{
return spl_object_hash($this);
}
}
I didn't know how to solve this problem.
With the latter issue, you're running PHP 7.0+ code with a version of PHP that is less than 7.0.
With PHP 7.0 came the support of function type hinting, IE:
public function getIsServerRequest(): bool
This states that the function getIsServerRequest will return a boolean, either true or false.
Make sure that you're running the correct version of PHP.
This may also solve the first issue once you have fixed the latter issue.
I have looked for other results for this case but couldn't fix it myself. I would be thankful if someone can help me with replacing this preg_replace with preg_replace_callback
preg_replace("/[-_]([a-z])/e", "ucfirst('\\1')", ucwords($verb));
<?php
/** #see Zang_Exception **/
require_once 'Exception.php';
/** #see Zang_Schemas **/
require_once 'Schemas.php';
/**
*
* A Zang InboundXML wrapper.
*
* Please consult the online documentation for more details.
* Online documentation can be found at: http://www.zang.io/docs/api/inboundxml/
*
* --------------------------------------------------------------------------------
*
* #category Zang Wrapper
* #package Zang
* #author Nevio Vesic <nevio#zang.io>
* #license http://creativecommons.org/licenses/MIT/ MIT
* #copyright (2012) Zang, Inc. <support#zang.io>
*/
class Zang_InboundXML
{
/**
* InboundXML simple xml element container
*
* #var null|SimpleXmlElement
*/
protected $element;
/**
* Current child pointer. Used for nesting validations
*
* #var string|null
*/
protected $_currentChild = null;
/**
* Constructs a InboundXML response.
*
* #param SimpleXmlElement|array $arg:
* - the element to wrap
* - attributes to add to the element
* - if null, initialize an empty element named 'Response'
*/
public function __construct($arg = null) {
switch (true) {
case $arg instanceof SimpleXmlElement:
$this->element = $arg;
$this->_currentChild = strtolower($arg->getName());
break;
case $arg === null:
$this->element = new SimpleXmlElement('<Response/>');
$this->_currentChild = 'response';
break;
case is_array($arg):
$this->element = new SimpleXmlElement('<Response/>');
$this->_currentChild = 'response';
foreach ($arg as $name => $value) {
$this->_validateAttribute($name, 'response');
$this->element->addAttribute($name, $value);
}
break;
default: throw new Zang_Exception('InboundXML Invalid construction argument');
}
}
/**
* Converts method calls into InboundXML verbs.
*
* #return SimpleXmlElement A SimpleXmlElement
*/
public function __call($verb, array $args) {
/** convert verbs input like-this-one to LikeThisOne **/
$verb = preg_replace("/[-_]([a-z])/e", "ucfirst('\\1')", ucwords($verb));
/** Let's first go check if the verb exists **/
$this->_validateVerb(ucfirst($verb));
/** Let's go validate nesting **/
$this->_validateNesting(ucfirst($verb));
list($noun, $attrs) = $args + array('', array());
if (is_array($noun)) list($attrs, $noun) = array($noun, '');
$child = empty($noun)
? $this->element->addChild(ucfirst($verb))
: $this->element->addChild(ucfirst($verb), $noun);
foreach ($attrs as $name => $value) {
/** Validation of verb attributes **/
$this->_validateAttribute($name, $verb);
$child->addAttribute($name, $value);
}
return new self($child);
}
/**
* Returns the object as XML.
*
* #return string The response as an XML string
*/
public function __toString() {
$xml = $this->element->asXml();
return str_replace(
'<?xml version="1.0" ?>',
'<?xml version="1.0" encoding="UTF-8" ?>',
$xml
);
}
/**
* Validate existance of the verb. Return true if exists, throw exception
* if fails.
*
* #param string $verb
* #throws Zang_Exception
* #return bool
*/
private function _validateVerb($verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isVerb(ucfirst($verb))) {
$available_verbs = implode(', ', $schemas->getAvailableVerbs());
throw new Zang_Exception(
"Verb '{$verb}' is not a valid InboundXML verb. Available verbs are: '{$available_verbs}'"
);
}
return true;
}
/**
* Validate if previous child allows this verb to be its child.
*
* #param string $verb
* #return boolean
* #throws Zang_Exception
*/
private function _validateNesting($verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isNestingAllowed(ucfirst($this->_currentChild), ucfirst($verb))) {
$nestable_verbs = implode(', ', $schemas->getNestableByVerbs(ucfirst($this->_currentChild)));
$current_verb = ucfirst($this->_currentChild);
$next_verb = ucfirst($verb);
throw new Zang_Exception(
"InboundXML element '{$current_verb}' does not support '{$next_verb}' element. The following elements are supported: '{$nestable_verbs}'."
);
}
return true;
}
/**
* Validate if attribute of verb exists. If not, throw exception, otherwise, return true.
*
* #param string $attr
* #param string $verb
* #return boolean
* #throws Zang_Exception
*/
private function _validateAttribute($attr, $verb) {
$schemas = Zang_Schemas::getInstance();
if(!$schemas->isValidAttribute($attr, ucfirst($verb))) {
$verb_attribuges = implode(', ', $schemas->getAvailableAttributes(ucfirst($verb)));
throw new Zang_Exception(
"Attribute '{$attr}' does not exist for verb '{$verb}'. Available attributes are: '{$verb_attribuges}'"
);
}
return true;
}
}
It is a bit unclear why you want to use another function. It might be this is because you are upgrading php and the e modifier is not supported any more. And the example code you posted suggest that you are trying to turn hyphen and underscore concatenated expressions into camel case...
Take a look at this simple demonstration:
<?php
$verb = 'this is a simple-test_sentence to convert.';
echo preg_replace_callback(
"/[-_]([a-z]+)/",
function($string) { return ucfirst($string[1]); },
ucwords($verb)
);
The output obviously is:
This Is A SimpleTestSentence To Convert.
I recently moved one of my sites to a new dedicated server running the latest version of PHP. In my php-based Knowledgebase section of the site, I am getting the following error:
Strict Standards: Declaration of API_RATING::multiDelete() should be compatible with API::multiDelete($ids = 0) in /home/givebrad/public_html/kb/lib/api/class.rating.php on line 156
Line 156 is the last closing } at the bottom of the file. Below is the code for class-rating.php. Can anyone help me out to figure out how to fix this?
<?php
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'class.api.php');
class API_RATING extends API
{
var $rateid = 0;
var $questionid = 0;
var $ip = '';
var $ratedat = '';
var $fields = array (
'rateid',
'questionid',
'ip',
'ratedat',
'ratingemail',
'ratingmessage'
);
var $pk = 'rateid';
/**
* create
* create a new rating in the database
*
* #return bool was the creation successful ?
*/
function create()
{
$_POST['ratedat'] = date('Y-m-d H:i:s');
$_POST['ip'] = $_SERVER['REMOTE_ADDR'];
return parent::create();
}
/**
* multiDelete
* Delete multiple rating ids. Update each associated question.
*
* #return bool was the delete successful?
*/
function multiDelete($ids) {
//Get the question ids
$objArray = $this->loadMultiByPK($ids);
foreach ($objArray as $rateObj) {
$questionObj = new API_QUESTION();
$questionObj->load($rateObj->questionid);
$questionObj->negvotes--;
$questionObj->score -= SCORE_MODIFIER;
$questionObj->updateField("negvotes", $questionObj->negvotes);
$questionObj->updateField("score", $questionObj->score);
}
//Delete from the main table
if (!parent::multiDelete($ids)) {
return false;
}
return true;
}
/**
* validate_rateid
*
* Ensure the rate id is a pos int
*
* #param string $var
*
* #return bool
*/
function validate_rateid($var)
{
return $this->is_positive_int($var);
}
/**
* validate_questionid
*
* Ensure the questionid is pos int
*
* #return bool
*/
function validate_questionid($var)
{
return $this->is_positive_int($var);
}
/**
* validate_ip
*
* Ensure the ip is an ipv4 address
*
* #param $var the ip to validate
*
* #return bool
*/
function validate_ip($var)
{
return $this->is_ip($var);
}
/**
* validate_ratedat
*
* Ensure the rated at date is in the standard date format
*
* #param string $var
*
* #return bool
*/
function validate_ratedat($var)
{
return $this->is_standard_date($var);
}
/**
* validate_email
*
* Ensure the email address for this rate entry is valid.
*
* #param string $var
*
* #return bool
*/
function validate_ratingemail(&$var)
{
if ((trim($var) == "") || (trim($var) == GetLang("WhyUnhelpfulEmail"))) {
$var = "";
return true;
} else {
return is_email_address($var);
}
}
/**
* validate_ratingmessage
*
* Ensure there is a message and its not blank.
*
* #param string $var
*
* #return bool
*/
function validate_ratingmessage(&$var)
{
if (strlen(trim($var)) > 250) {
$var = substr(trim($var),0,250);
return true;
} else {
return (trim($var) != "");
}
}
}
?>
This function :
function multiDelete($ids) {
Should be identic with it's parent function, find out the same function in class API, the nums, default value and type of the params should be same;
I asked this before, Strict Standards: Declaration of ' ' should be compatible with ' '
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
WAMP Stack PHP “Fatal error: Class ‘SoapClient’ not found”
I downloaded a library from this site library and when I tried to use it's examples it says : "Fatal error: Class 'SoapClient' not found in C:\wamp\www\Amazon-ECS\Exeu-Amazon-ECS-PHP-Library-9030053\lib\AmazonECS.class.php on line 231" How should I able to fix this?
<?php
/**
* Amazon ECS Class
* http://www.amazon.com
* =====================
*
* This class fetchs productinformation via the Product Advertising API by Amazon (formerly ECS).
* It supports three basic operations: ItemSearch, ItemLookup and BrowseNodeLookup.
* These operations could be expanded with extra prarmeters to specialize the query.
*
* Requirement is the PHP extension SOAP.
*
* #package AmazonECS
* #license http://www.gnu.org/licenses/gpl.txt GPL
* #version 1.3.4-DEV
* #author Exeu <exeu65#googlemail.com>
* #contributor Julien Chaumond <chaumond#gmail.com>
* #link http://github.com/Exeu/Amazon-ECS-PHP-Library/wiki Wiki
* #link http://github.com/Exeu/Amazon-ECS-PHP-Library Source
*/
class AmazonECS
{
const RETURN_TYPE_ARRAY = 1;
const RETURN_TYPE_OBJECT = 2;
/**
* Baseconfigurationstorage
*
* #var array
*/
private $requestConfig = array(
'requestDelay' => false
);
/**
* Responseconfigurationstorage
*
* #var array
*/
private $responseConfig = array(
'returnType' => self::RETURN_TYPE_OBJECT,
'responseGroup' => 'Small',
'optionalParameters' => array()
);
/**
* All possible locations
*
* #var array
*/
private $possibleLocations = array('de', 'com', 'co.uk', 'ca', 'fr', 'co.jp', 'it', 'cn', 'es');
/**
* The WSDL File
*
* #var string
*/
protected $webserviceWsdl = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl';
/**
* The SOAP Endpoint
*
* #var string
*/
protected $webserviceEndpoint = 'https://webservices.amazon.%%COUNTRY%%/onca/soap?Service=AWSECommerceService';
/**
* #param string $accessKey
* #param string $secretKey
* #param string $country
* #param string $associateTag
*/
public function __construct($accessKey, $secretKey, $country, $associateTag)
{
if (empty($accessKey) || empty($secretKey))
{
throw new Exception('No Access Key or Secret Key has been set');
}
$this->requestConfig['accessKey'] = $accessKey;
$this->requestConfig['secretKey'] = $secretKey;
$this->associateTag($associateTag);
$this->country($country);
}
/**
* execute search
*
* #param string $pattern
*
* #return array|object return type depends on setting
*
* #see returnType()
*/
public function search($pattern, $nodeId = null)
{
if (false === isset($this->requestConfig['category']))
{
throw new Exception('No Category given: Please set it up before');
}
$browseNode = array();
if (null !== $nodeId && true === $this->validateNodeId($nodeId))
{
$browseNode = array('BrowseNode' => $nodeId);
}
$params = $this->buildRequestParams('ItemSearch', array_merge(
array(
'Keywords' => $pattern,
'SearchIndex' => $this->requestConfig['category']
),
$browseNode
));
return $this->returnData(
$this->performSoapRequest("ItemSearch", $params)
);
}
/**
* execute ItemLookup request
*
* #param string $asin
*
* #return array|object return type depends on setting
*
* #see returnType()
*/
public function lookup($asin)
{
$params = $this->buildRequestParams('ItemLookup', array(
'ItemId' => $asin,
));
return $this->returnData(
$this->performSoapRequest("ItemLookup", $params)
);
}
/**
* Implementation of BrowseNodeLookup
* This allows to fetch information about nodes (children anchestors, etc.)
*
* #param integer $nodeId
*/
public function browseNodeLookup($nodeId)
{
$this->validateNodeId($nodeId);
$params = $this->buildRequestParams('BrowseNodeLookup', array(
'BrowseNodeId' => $nodeId
));
return $this->returnData(
$this->performSoapRequest("BrowseNodeLookup", $params)
);
}
/**
* Implementation of SimilarityLookup
* This allows to fetch information about product related to the parameter product
*
* #param string $asin
*/
public function similarityLookup($asin)
{
$params = $this->buildRequestParams('SimilarityLookup', array(
'ItemId' => $asin
));
return $this->returnData(
$this->performSoapRequest("SimilarityLookup", $params)
);
}
/**
* Builds the request parameters
*
* #param string $function
* #param array $params
*
* #return array
*/
protected function buildRequestParams($function, array $params)
{
$associateTag = array();
if(false === empty($this->requestConfig['associateTag']))
{
$associateTag = array('AssociateTag' => $this->requestConfig['associateTag']);
}
return array_merge(
$associateTag,
array(
'AWSAccessKeyId' => $this->requestConfig['accessKey'],
'Request' => array_merge(
array('Operation' => $function),
$params,
$this->responseConfig['optionalParameters'],
array('ResponseGroup' => $this->prepareResponseGroup())
)));
}
/**
* Prepares the responsegroups and returns them as array
*
* #return array|prepared responsegroups
*/
protected function prepareResponseGroup()
{
if (false === strstr($this->responseConfig['responseGroup'], ','))
return $this->responseConfig['responseGroup'];
return explode(',', $this->responseConfig['responseGroup']);
}
/**
* #param string $function Name of the function which should be called
* #param array $params Requestparameters 'ParameterName' => 'ParameterValue'
*
* #return array The response as an array with stdClass objects
*/
protected function performSoapRequest($function, $params)
{
if (true === $this->requestConfig['requestDelay']) {
sleep(1);
}
$soapClient = new SoapClient(
$this->webserviceWsdl,
array('exceptions' => 1)
);
$soapClient->__setLocation(str_replace(
'%%COUNTRY%%',
$this->responseConfig['country'],
$this->webserviceEndpoint
));
$soapClient->__setSoapHeaders($this->buildSoapHeader($function));
return $soapClient->__soapCall($function, array($params));
}
/**
* Provides some necessary soap headers
*
* #param string $function
*
* #return array Each element is a concrete SoapHeader object
*/
protected function buildSoapHeader($function)
{
$timeStamp = $this->getTimestamp();
$signature = $this->buildSignature($function . $timeStamp);
return array(
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'AWSAccessKeyId',
$this->requestConfig['accessKey']
),
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'Timestamp',
$timeStamp
),
new SoapHeader(
'http://security.amazonaws.com/doc/2007-01-01/',
'Signature',
$signature
)
);
}
/**
* provides current gm date
*
* primary needed for the signature
*
* #return string
*/
final protected function getTimestamp()
{
return gmdate("Y-m-d\TH:i:s\Z");
}
/**
* provides the signature
*
* #return string
*/
final protected function buildSignature($request)
{
return base64_encode(hash_hmac("sha256", $request, $this->requestConfig['secretKey'], true));
}
/**
* Basic validation of the nodeId
*
* #param integer $nodeId
*
* #return boolean
*/
final protected function validateNodeId($nodeId)
{
if (false === is_numeric($nodeId) || $nodeId <= 0)
{
throw new InvalidArgumentException(sprintf('Node has to be a positive Integer.'));
}
return true;
}
/**
* Returns the response either as Array or Array/Object
*
* #param object $object
*
* #return mixed
*/
protected function returnData($object)
{
switch ($this->responseConfig['returnType'])
{
case self::RETURN_TYPE_OBJECT:
return $object;
break;
case self::RETURN_TYPE_ARRAY:
return $this->objectToArray($object);
break;
default:
throw new InvalidArgumentException(sprintf(
"Unknwon return type %s", $this->responseConfig['returnType']
));
break;
}
}
/**
* Transforms the responseobject to an array
*
* #param object $object
*
* #return array An arrayrepresentation of the given object
*/
protected function objectToArray($object)
{
$out = array();
foreach ($object as $key => $value)
{
switch (true)
{
case is_object($value):
$out[$key] = $this->objectToArray($value);
break;
case is_array($value):
$out[$key] = $this->objectToArray($value);
break;
default:
$out[$key] = $value;
break;
}
}
return $out;
}
/**
* set or get optional parameters
*
* if the argument params is null it will reutrn the current parameters,
* otherwise it will set the params and return itself.
*
* #param array $params the optional parameters
*
* #return array|AmazonECS depends on params argument
*/
public function optionalParameters($params = null)
{
if (null === $params)
{
return $this->responseConfig['optionalParameters'];
}
if (false === is_array($params))
{
throw new InvalidArgumentException(sprintf(
"%s is no valid parameter: Use an array with Key => Value Pairs", $params
));
}
$this->responseConfig['optionalParameters'] = $params;
return $this;
}
/**
* Set or get the country
*
* if the country argument is null it will return the current
* country, otherwise it will set the country and return itself.
*
* #param string|null $country
*
* #return string|AmazonECS depends on country argument
*/
public function country($country = null)
{
if (null === $country)
{
return $this->responseConfig['country'];
}
if (false === in_array(strtolower($country), $this->possibleLocations))
{
throw new InvalidArgumentException(sprintf(
"Invalid Country-Code: %s! Possible Country-Codes: %s",
$country,
implode(', ', $this->possibleLocations)
));
}
$this->responseConfig['country'] = strtolower($country);
return $this;
}
/**
* Setting/Getting the amazon category
*
* #param string $category
*
* #return string|AmazonECS depends on category argument
*/
public function category($category = null)
{
if (null === $category)
{
return isset($this->requestConfig['category']) ? $this->requestConfig['category'] : null;
}
$this->requestConfig['category'] = $category;
return $this;
}
/**
* Setting/Getting the responsegroup
*
* #param string $responseGroup Comma separated groups
*
* #return string|AmazonECS depends on responseGroup argument
*/
public function responseGroup($responseGroup = null)
{
if (null === $responseGroup)
{
return $this->responseConfig['responseGroup'];
}
$this->responseConfig['responseGroup'] = $responseGroup;
return $this;
}
/**
* Setting/Getting the returntype
* It can be an object or an array
*
* #param integer $type Use the constants RETURN_TYPE_ARRAY or RETURN_TYPE_OBJECT
*
* #return integer|AmazonECS depends on type argument
*/
public function returnType($type = null)
{
if (null === $type)
{
return $this->responseConfig['returnType'];
}
$this->responseConfig['returnType'] = $type;
return $this;
}
/**
* Setter/Getter of the AssociateTag.
* This could be used for late bindings of this attribute
*
* #param string $associateTag
*
* #return string|AmazonECS depends on associateTag argument
*/
public function associateTag($associateTag = null)
{
if (null === $associateTag)
{
return $this->requestConfig['associateTag'];
}
$this->requestConfig['associateTag'] = $associateTag;
return $this;
}
/**
* #deprecated use returnType() instead
*/
public function setReturnType($type)
{
return $this->returnType($type);
}
/**
* Setting the resultpage to a specified value.
* Allows to browse resultsets which have more than one page.
*
* #param integer $page
*
* #return AmazonECS
*/
public function page($page)
{
if (false === is_numeric($page) || $page <= 0)
{
throw new InvalidArgumentException(sprintf(
'%s is an invalid page value. It has to be numeric and positive',
$page
));
}
$this->responseConfig['optionalParameters'] = array_merge(
$this->responseConfig['optionalParameters'],
array("ItemPage" => $page)
);
return $this;
}
/**
* Enables or disables the request delay.
* If it is enabled (true) every request is delayed one second to get rid of the api request limit.
*
* Reasons for this you can read on this site:
* https://affiliate-program.amazon.com/gp/advertising/api/detail/faq.html
*
* By default the requestdelay is disabled
*
* #param boolean $enable true = enabled, false = disabled
*
* #return boolean|AmazonECS depends on enable argument
*/
public function requestDelay($enable = null)
{
if (false === is_null($enable) && true === is_bool($enable))
{
$this->requestConfig['requestDelay'] = $enable;
return $this;
}
return $this->requestConfig['requestDelay'];
}
}
The error appears to be caused by the version of PHP that you have does not have the SOAP extension enabled.
To resolve this simply start wamp, click on the wamp system tray icon. Within this screen select PHP then PHP extensions. This will display a list of extensions. Ensure that php_soap is ticked.
If you intend to access soap servers that use HTTPs then you will also ensure php_openssl is ticked.
I have the following php code (getRout.php).. which response results in xml formats ... But I got this error :
XML Parsing Error: no element found
Location: http://127.0.0.1/direction2/getRout.php
Line Number 1, Column 1:
edit
You can see the xml response directly by requesting this url :
http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik
getRout.php
<? require_once"RESTclient.class.php";
$url="http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik";
$result=RestClient::get($url,$inputs);
header("Content-type:text/xml");
echo($result->getResponse());?>
RESTclient.class.php
<?
/**
* Class RestClient
* Wraps HTTP calls using cURL, aimed for accessing and testing RESTful webservice.
* By Diogo Souza da Silva <manifesto#manifesto.blog.br>
*/
class RestClient {
private $curl ;
private $url ;
private $response ="";
private $headers = array();
private $method="GET";
private $params=null;
private $contentType = null;
private $file =null;
/**
* Private Constructor, sets default options
*/
private function __construct() {
$this->curl = curl_init();
curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($this->curl,CURLOPT_AUTOREFERER,true); // This make sure will follow redirects
curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION,true); // This too
curl_setopt($this->curl,CURLOPT_HEADER,true); // THis verbose option for extracting the headers
}
/**
* Execute the call to the webservice
* #return RestClient
*/
public function execute() {
if($this->method === "POST") {
curl_setopt($this->curl,CURLOPT_POST,true);
curl_setopt($this->curl,CURLOPT_POSTFIELDS,$this->params);
} else if($this->method == "GET"){
curl_setopt($this->curl,CURLOPT_HTTPGET,true);
$this->treatURL();
} else if($this->method === "PUT") {
curl_setopt($this->curl,CURLOPT_PUT,true);
$this->treatURL();
$this->file = tmpFile();
fwrite($this->file,$this->params);
fseek($this->file,0);
curl_setopt($this->curl,CURLOPT_INFILE,$this->file);
curl_setopt($this->curl,CURLOPT_INFILESIZE,strlen($this->params));
} else {
curl_setopt($this->curl,CURLOPT_CUSTOMREQUEST,$this->method);
}
if($this->contentType != null) {
curl_setopt($this->curl,CURLOPT_HTTPHEADER,array("Content-Type: ".$this->contentType));
}
curl_setopt($this->curl,CURLOPT_URL,$this->url);
$r = curl_exec($this->curl);
$this->treatResponse($r); // Extract the headers and response
return $this ;
}
/**
* Treats URL
*/
private function treatURL(){
if(is_array($this->params) && count($this->params) >= 1) { // Transform parameters in key/value pars in URL
if(!strpos($this->url,'?'))
$this->url .= '?' ;
foreach($this->params as $k=>$v) {
$this->url .= "&".urlencode($k)."=".urlencode($v);
}
}
return $this->url;
}
/*
* Treats the Response for extracting the Headers and Response
*/
private function treatResponse($r) {
if($r == null or strlen($r) < 1) {
return;
}
$parts = explode("\n\r",$r); // HTTP packets define that Headers end in a blank line (\n\r) where starts the body
while(preg_match('#HTTP/1.[0-1] 100 Continue#',$parts[0]) or preg_match("#Moved#",$parts[0])) {
// Continue header must be bypass
for($i=1;$i<count($parts);$i++) {
$parts[$i - 1] = trim($parts[$i]);
}
unset($parts[count($parts) - 1]);
}
preg_match("#Content-Type: ([a-zA-Z0-9-]+/?[a-zA-Z0-9-]*)#",$parts[0],$reg);// This extract the content type
$this->headers['content-type'] = $reg[1];
preg_match("#HTTP/1.[0-1] ([0-9]{3}) ([a-zA-Z ]+)#",$parts[0],$reg); // This extracts the response header Code and Message
$this->headers['code'] = $reg[1];
$this->headers['message'] = $reg[2];
$this->response = "";
for($i=1;$i<count($parts);$i++) {//This make sure that exploded response get back togheter
if($i > 1) {
$this->response .= "\n\r";
}
$this->response .= $parts[$i];
}
}
/*
* #return array
*/
public function getHeaders() {
return $this->headers;
}
/*
* #return string
*/
public function getResponse() {
return $this->response ;
}
/*
* HTTP response code (404,401,200,etc)
* #return int
*/
public function getResponseCode() {
return (int) $this->headers['code'];
}
/*
* HTTP response message (Not Found, Continue, etc )
* #return string
*/
public function getResponseMessage() {
return $this->headers['message'];
}
/*
* Content-Type (text/plain, application/xml, etc)
* #return string
*/
public function getResponseContentType() {
return $this->headers['content-type'];
}
/**
* This sets that will not follow redirects
* #return RestClient
*/
public function setNoFollow() {
curl_setopt($this->curl,CURLOPT_AUTOREFERER,false);
curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION,false);
return $this;
}
/**
* This closes the connection and release resources
* #return RestClient
*/
public function close() {
curl_close($this->curl);
$this->curl = null ;
if($this->file !=null) {
fclose($this->file);
}
return $this ;
}
/**
* Sets the URL to be Called
* #return RestClient
*/
public function setUrl($url) {
$this->url = $url;
return $this;
}
/**
* Set the Content-Type of the request to be send
* Format like "application/xml" or "text/plain" or other
* #param string $contentType
* #return RestClient
*/
public function setContentType($contentType) {
$this->contentType = $contentType;
return $this;
}
/**
* Set the Credentials for BASIC Authentication
* #param string $user
* #param string $pass
* #return RestClient
*/
public function setCredentials($user,$pass) {
if($user != null) {
curl_setopt($this->curl,CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
curl_setopt($this->curl,CURLOPT_USERPWD,"{$user}:{$pass}");
}
return $this;
}
/**
* Set the Request HTTP Method
* For now, only accepts GET and POST
* #param string $method
* #return RestClient
*/
public function setMethod($method) {
$this->method=$method;
return $this;
}
/**
* Set Parameters to be send on the request
* It can be both a key/value par array (as in array("key"=>"value"))
* or a string containing the body of the request, like a XML, JSON or other
* Proper content-type should be set for the body if not a array
* #param mixed $params
* #return RestClient
*/
public function setParameters($params) {
$this->params=$params;
return $this;
}
/**
* Creates the RESTClient
* #param string $url=null [optional]
* #return RestClient
*/
public static function createClient($url=null) {
$client = new RestClient ;
if($url != null) {
$client->setUrl($url);
}
return $client;
}
/**
* Convenience method wrapping a commom POST call
* #param string $url
* #param mixed params
* #param string $user=null [optional]
* #param string $password=null [optional]
* #param string $contentType="multpary/form-data" [optional] commom post (multipart/form-data) as default
* #return RestClient
*/
public static function post($url,$params=null,$user=null,$pwd=null,$contentType="multipart/form-data") {
return self::call("POST",$url,$params,$user,$pwd,$contentType);
}
/**
* Convenience method wrapping a commom PUT call
* #param string $url
* #param string $body
* #param string $user=null [optional]
* #param string $password=null [optional]
* #param string $contentType=null [optional]
* #return RestClient
*/
public static function put($url,$body,$user=null,$pwd=null,$contentType=null) {
return self::call("PUT",$url,$body,$user,$pwd,$contentType);
}
/**
* Convenience method wrapping a commom GET call
* #param string $url
* #param array params
* #param string $user=null [optional]
* #param string $password=null [optional]
* #return RestClient
*/
public static function get($url,array $params=null,$user=null,$pwd=null) {
return self::call("GET",$url,$params,$user,$pwd);
}
/**
* Convenience method wrapping a commom delete call
* #param string $url
* #param array params
* #param string $user=null [optional]
* #param string $password=null [optional]
* #return RestClient
*/
public static function delete($url,array $params=null,$user=null,$pwd=null) {
return self::call("DELETE",$url,$params,$user,$pwd);
}
/**
* Convenience method wrapping a commom custom call
* #param string $method
* #param string $url
* #param string $body
* #param string $user=null [optional]
* #param string $password=null [optional]
* #param string $contentType=null [optional]
* #return RestClient
*/
public static function call($method,$url,$body,$user=null,$pwd=null,$contentType=null) {
return self::createClient($url)
->setParameters($body)
->setMethod($method)
->setCredentials($user,$pwd)
->setContentType($contentType)
->execute()
->close();
}
}
?>
There's no problem in the xml. the problem you see in your browser is due to the empty characters before the start of the xml tag.
If you do a var_dump you'll see something like:
string(5726) " <--- carriage return
<?xml version="1.0" encoding="UTF-8"?>
You should change the treatResponse() method on the class, I solved it like this:
private function treatResponse($r) {
....
for($i=1;$i<count($parts);$i++) {
if($i > 1) {
$this->response .= "\n\r";
}
$this->response .= trim($parts[$i]);
}
}
hope this helps
Note: that empty line comes from the HTTP protocol that says that there should be an empty line after the headers http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_message
There is a line break before the xml declaration in the output because RestClient::treatResponse($r) doesn't "treat" the response as it should ;-)
I'd rather set curl_setopt($this->curl,CURLOPT_HEADER, false) in the constructor and reduce treatResponse() to
private function treatResponse($r) {
$this->response = $r;
$this->headers['content-type'] = curl_getinfo($this->curl, CURLINFO_CONTENT_TYPE);
$this->headers['code'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
// ok, that's not exactly the same ....
$this->headers['message'] = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
}
Ran your code - only error I got was:
Notice: Undefined variable: inputs
Removing $inputs - no errors
This worked for me
<?php
require_once("RESTclient.class.php");
$url="http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=52.215676&flon=5.963946&tlat=52.2573&tlon=6.1799&v=motorcar&fast=1&layer=mapnik";
$result=RestClient::get($url); // removed $input as suggested by Dan J
header("Content-type:text/xml");
echo(trim($result->getResponse())); // added trim to remove blank line before
// xml declaration
?>