I have a list of functions that runs a fairly deep routine to determine which post_id to get its content from and output it on the site's frontend.
When this function returns its content I want it to be wrapped in an html wrapper. I want this html wrapper to only load if the function has an output to return.
In example, I have the following...
public static function output_*() {
// my routines that check for content to output precede here
// if there IS content to output the output will end in echo $output;
// if there is NO content to output the output will end in return;
}
In full explanation, I have the following...
If one of these functions returns an output I want it to be wrapped in an html wrapper, so in theory something like this is what I am trying to accomplish...
public static function begin_header_wrapper() {
// This only returns true if an output function below returns content,
// which for me is other than an empty return;
include(self::$begin_header_wrapper);
}
public static function output_above_header() {
// my routines that check for content to output precede here
// if there is content to return it will end in the following statement
// otherwise it will end in return;
include($begin_markup); // This is the BEGIN html wrapper for this specifc output
// It is, so let's get this option's post id number, extract its content,
// run any needed filters and output our user's selected content
$selected_content = get_post($this_option);
$extracted_content = kc_raw_content($selected_content);
$content = kc_do_shortcode($extracted_content);
echo $content;
include($end_markup); // This is the END html wrapper for this specifc output
}
public static function output_header() {
// the same routine as above but for the header output
}
public static function output_below_header() {
// the same routine as above but for the below header output
}
public static function end_header_wrapper() {
// This only returns true if an output function above returns content,
// which for me is other than an empty return;
include(self::$end_header_wrapper);
}
I know right now, ahead of time I don't want to determine twice (once in the start and once at the end) if one of the output functions has an output, when there should be a way to do this with one check, but I would like to get started down this rabbit hole and figure out the best way to determine if my function is returning something or not.
Or if there is an entirely better way to approach this please go all out, lol and let me know.
I looked online at this article and others
# Find out if function has any output with php
So in the end, I just wanted to know if there is a better way to approach this and what is actually the BEST way you think to check if my functions have an output to return so I can run my html wrapper based on those conditions?
Would ob_get_length be the best way? As I looked over the ob purposes, this one seemed best, and most simplistic, but wanted to get some advice, feedback. Or maybe I can check if my variable $content is returned? Thanks. Really appreciate it!
You can catch the result and store it in a variable, which is then given to the empty() function.
if(!empty(($output = yourFunctionToTest(param1, paramN)))) {
// do something with $output (in this case there is some output
// which isn't considered "empty"
}
This executes your function, stores the output in a variable ($output in this case) and executes empty() to check the variables content.
You are able to use the content of $output afterwards.
Be aware that empty() consideres empty strings or 0 as "empty", therefore returning true.
As an alternative you may use functions like isset() to determine if a variable is not null.
http://php.net/isset
http://php.net/empty
Related
The code is saved to database from plain textarea and stored exactly as [php]echo $clientMenu;[/php] then read into the document by a process. However the value is either rendered as plain text or not shown because the tags are being converted to comments <!--?php $clientMenu; ?-->, and I suspect the latter result is due to the parent application which is WISECP using method remove_noise() of class simple_html_dom (https://simplehtmldom.sourceforge.io/docs/1.9/index.html) to block the output for security and I haven't figured a method to override it.
I tried using eval() and the return is just echo ;
My coding to process the string and output as functional PHP
private static function codeblock($codeblock)
{
if( preg_match_all('#\[php\](.*?)\[\/php\]#is', $codeblock, $phpcode, PREG_SET_ORDER) ) {
foreach($phpcode as $php) {
$code = '<?php '.$php[1].' ?>';
$codeblock = str_replace($php[0], $code, $codeblock);
}
}
return $codeblock;
}
The value is passed to the output method to render in the HTML document
echo wcp::htmlRender()->head; The data for $clientMenu is already within the PHP file where the HTML is rendered.
All efforts to get the process to work have failed and I am at wits end after too many hours. I would certainly appreciate any assistance.
edit
The reason for the comment result in the HTML document is due to the output being written in the page as rendered HTML and that's not the intent.
I used eval() (yes I know it is evil) and realize that the PHP variable is being evaluated but is returning empty. So clearly is not associating with the stored value. What is the alternative to eval() to parse coding string as functional PHP
String from DB [php]$clientMenu[/php]
private static function codeblock($codeblock)
{
if( preg_match_all('#\[php\](.*?)\[\/php\]#is', $codeblock, $phpcode, PREG_SET_ORDER) ) {
foreach($phpcode as $php) {
eval("\$da = \"$php[1]\";");
$codeblock = str_replace($php[0], $da, $codeblock);
}
}
return $codeblock;
}
html_entity_decode function will help you with conversion to the actual code.
https://www.php.net/manual/en/function.html-entity-decode.php
I am a newbie in php and rest and I'm trying to understand what is going on in my API when using echo vs return....
I've tried to get down to the simplest possible scenario to isolate an issue of my rest API not returning any value, so here is goes:
I have a test.php file on my server with following content:
<?php
if(function_exists($_GET['t1'])) {
echo $_GET['t1']();
}
else if(function_exists($_GET['t2'])) {
return $_GET['t2']();
}
function test() {
return json_encode("test...");
}
?>
I then make a simple request using, as unique header 'Content-Type: application/json`
https://www.eswys.ch/tmp/test.php?t1=test
https://www.eswys.ch/tmp/test.php?t2=test
And results are, respectively
"test..."
""
I really struggle to understand this, why is my returned value somehow "lost" - is there any explanation to this?!
Returning from a function does not actually render any content to the response. You may have seen people returning data in different frameworks but the framework is actually echoing the data for you behind the scenes.
return assigns a value to a function call (like a variable) and echo is simply output to the html page or possibly a terminal window.
I have a function that creates an array that contains the return value from the HTML DOM method : window.document.getElementById()
function makearray1(){
var array1=[1,window.document.getElementById('divID'),['a','b'],[1,2]];
}
then I pass the array into another function
use(array1)
function use(xxx){
xxx[1].innerHTML=xxx[2][0];
}
and 'a' is written in the appropriate div
later I decided to put the array in a form and post it to a txt file on the server using php and:
JSON.stringify(array)
So now I use AJAX to call the data from the txt file after the rest of the page has loaded etc... and the original function used to make the array is not included at all.
so my php is basically this:
$a1='use(';
$data1 =file_get_contents("text_file.txt") ;
$a2=')';
echo $a1.$data1.$a2;
and the response text:
var n= XMLHttpRequestObject.responseText;
eval(n);
which pretty much means this:
use(text_file)
function use(xxx){
xxx[1].innerHTML=xxx[2][0];
}
the problem is that the array in the text file looks like this:
[1,null,['a','b'],[1,2]]
instead of:
[1,window.document.getElementById('divID'),['a','b'],[1,2]]
My question: Is there any way that I can do the equivalent of what I'm trying to do here, which is immediately replicate the return value of the HTML/DOM method in an array using AJAX/php?
To clarify: this is a simple example. I actually have a huge, multidimensional array that already has established pointers, or prefetched DOM nodes in it. Now I'm trying to replicate the array when a text version is loaded using ajax. I'm looking for a recursive approach to changing all of the null assignments with something that will immediately fetch the appropriate DOM node. Most likely I will need to do it with the response text, but was hoping I could do it with the php portion.
You're trying to stringify a reference to a javascript object in the memory of whatever computer is evaluating getElementById first, and that has no chance to represent something on the end client's computer.
Send the id instead:
function makearray1(){
array1=[1,'divID',['a','b'],[1,2]];
}
then, in the client:
function use(xxx){
window.document.getElementById(xxx[1]).innerHTML=xxx[2][0];
}
If you really want to eval it at the end, you can use this, I guess
function makearray1(){
array1=[1,"window.document.getElementById(\"divID\")",['a','b'],[1,2]];
}
I've no idea why you would want to do that though
Assuming the dom element exists in the second page, it should look something like this.
JS:
function packDomData(){
return {
"MySpecificYetBriefProperty0":1,
"DomID":"divID",
"MySpecificYetBriefProperty1":['a','b'],
"MySpecificYetBriefProperty2":[1,2]
};
}
function useDomData(domData){
document.getElementByID(domData.DomID).innerHTML=domData.MySpecificYetBriefProperty1[0];
}
PHP:
//Make sure the contents of this file is the json from packDomData. use json_encode in php or JSON.stringify in js
echo file_get_contents("text_file.txt");
var myData = JSON.parse(XMLHttpRequestObject.responseText);
useDomData(myData);
I used to code like you. Here are some tips that have helped turn my coding horror into a fun job:
Use objects with descriptive properties instead of arrays whenever you aren't actually looping through the array - I promise it will save you and others headache! "DomID" is much more flexible than 1, and if you change the order in the array, javascript gods help you that array is everywhere - including however many random text files on your server!
Also use descriptive names for functions
Always return a value from a function instead of using globals whenever possible, even where the result is then used as a nasty global. Trust me.
Never put javascript function names in an ajax call. Use JSON instead and keep the functions and other script in the javascript file where it belongs.
Mysql will save your life!!
Disclaimer - I didn't run this code but it should basically work when you get everything hooked up right.
In PHP have a situation where I need the page to be mostly executed, but have an item inserted into the output from that page.
I think output buffering may be of some help, but I can't work out how to implement it in my situation.
My code looks like this:
//this document is part of a global functions file
function pageHeader (){
//I'm using $GLOBALS here because it works, however I would really rather a better method if possible
$GLOBALS['error_handler'] = new ErrorHandler(); //ErrorHandler class sets a function for set_error_handler, which gets an array of errors from the executed page
require_once($_SERVER['DOCUMENT_ROOT'].'/sales/global/_header.php');
//I would like the unordered list from ->displayErrorNotice() to be displayed here, but if I do that the list is empty because the list was output before the rest of the document was executed
}
function pageFooter (){
$GLOBALS['error_handler'] ->displayErrorNotice(); //this function displays the errors as an html unordered list
include($_SERVER['DOCUMENT_ROOT']."/sales/global/_footer.php");
}
Most pages on the site include this document and use the pageHeader() and pageFooter() functions. What I am trying to achieve is to put an unordered list of the PHP generated errors into an HTML list just at a point after _header.php has been included. I can get the list to work as intended if I put it in the footer (after the document has been executed), but I don't want it there. I guess I could move it with JS, but I think there must be a PHP solution.
UPDATE
I'm wondering whether a callback function for ob_start() which searches the buffer by regex where to put the error list, and then inserts it will be the solution.
UPDATE 2 I have solved the problem, my answer is below. I will accept it in 2 days when I am allowed.
Worked it out finally. The key was to buffer the output, and search the buffer for a given snippet of html, and replace it with the unordered list.
My implementation is like this:
function outputBufferCallback($buffer){
return str_replace("<insert_errors>", $GLOBALS['error_handler']->returnErrorNotice(), $buffer);
}
function pageHeader (){
ob_start('outputBufferCallback');
//I'm using $GLOBALS here because it works, however I would really rather a better method if possible
$GLOBALS['error_handler'] = new ErrorHandler(); //ErrorHandler class sets a function for set_error_handler, which gets an array of errors from the executed page
require_once($_SERVER['DOCUMENT_ROOT'].'/sales/global/_header.php');
echo '<insert_errors>'; //this snippet is replaced by the ul at buffer flush
}
function pageFooter (){
include($_SERVER['DOCUMENT_ROOT']."/sales/global/_footer.php");
ob_end_flush();
}
If I'm getting this right, you're trying to insert some calculated code/errors between the header and footer. I'm guessing that the errors are being totalled/summed up at the very end of the page and would be completed after the page footer.
If this is true, I can't think of anyway to do this with pure php. It can only run through a page once, and cannot double back. What you can do is create an element after the footer and move it using javascript to the area where you want to display it. This would be the easiest way I would think. You can do this easily with jquery.
I can explain further if I am on the right track, but I'm not 100% sure what you're asking yet...
The jquery command you would use is .appendTo().
The documentation on snippets in modx: http://rtfm.modx.com/display/revolution20/Snippets
Near the top of the doc it says: Note how we returned the code rather than echo'ed the content out. Never use echo in a Snippet - always return the output.
This doesn't display anything:
return $product_attribute $product_info[0][$column_name];
This does display:
echo $product_attribute $product_info[0][$column_name];
If I can't echo the content how do I get it to print in the html page?
It basically means that you can echo the returned value rather than echo the value in the function itself. In OOP programming, echoing (or printing) to the screen is strictly monitored.
For example I have this function
function testExample($var) {
return $var*2;
}
So when I need to echo it, I just need to
echo testExample(5);
Instead of this (bad practice)
function testExample($var) {
echo $var*2;
}
The reason is that when you print value in the function, you can only use that function for printing the value, which isn't reusable at all. But by returning it, you can now use it for printing, or assigning to another variable or re-calculating on it.
From what I can understand from the note, there is a convention not to use echo inside a function, but rather return the value and perhaps echo it afterwards.
Other printing posibilities would be:
print $your_variable;
or die($your_variable);
return is used to return values from a function/method ect
The snippet functionality of modx is actually just a function/class wrapper.