Reliably read value of PHP display_errors - error-handling

In my PHP error handler I want to do something like:
if (ini_get('display_errors') IS ON)) {
// show debug info
} else {
// show just "oops!"
}
I've look through the docs and stuff, but I can't really find out what the possible values for display_errors are (such as "on", 0, "Yes") and what it does for what value.
What should I put in place of the "IS ON" to reliably read this value?

I use the following code:
if (in_array(strtolower(ini_get('display_errors')), ['1', 'yes', 'on', 'true']) {
// is enabled
} else {
// is disabled
}
Or regexp
if (preg_match('/^(1|yes|on|true)$/i', ini_get('display_errors')) {
// is enabled
} else {
// is disabled
}

You can get the string representation of the values through ini_get(), values that display_errors can be set to is either, true\false, 0\1 and On\Off. But when user's set their php.ini it is more common to use 1 or On
if (ini_get('display_errors') == "1") {
// show debug info
}
or to check for ALL cases, you can perform a switch-case
ini_set('display_errors', 1);
switch (ini_get('display_errors')) {
case "1":
case "On":
case "true":
// show debug info
}
If you prefer the equality comparison approach, notice that ini_get returns a String value of 1, if you test the returned value with ini_get using the == with the int value 1, it becomes true. If you use the === it checks if both are equal and of the same type. String is not the same type as int so it would return false.
1 == "1"; // in PHP, this returns true, it doesn't check the type.
1 === "1"; // would be false, this however checks the type.
Using ini_get('display_errors') you can check against values like, TRUE, FALSE, and
even NULL. They will return a boolean value of either 0 which is false and anything other than 0 evaluates to true.
if (2) {
echo "2 is true!"; // echos "2 is true!"
}
I saw your comment about a discrepancy so I decided to test it myself, here is what I used
<?php
ini_set('display_errors', 1);
$verbose = ini_get('display_errors');
echo $verbose; // echo's 1
// just to test its return values.
if ($verbose) {
echo "verbose is true"; // echos "verbose is true"
}
ini_set('display_errors', 0);
$verbose = ini_get('display_errors');
echo $verbose; // echo's 0
if ($verbose) {
echo "verbose is not true"; // does not get evaluated
}
?>
This answer is a bit lengthy, but I hope this is what you need.

Use filter_var
if ( filter_var( ini_get('display_errors'), FILTER_VALIDATE_BOOLEAN) ){
}
And that should catch all of the different ways display_errors could get turned on ("1", "true", "on", "yes", etc.).
I also can't find any official documentation on this, but from what I've experienced, I believe using filter_var with the FILTER_VALIDATE_BOOLEAN flag will cover the full gamut of possible ways an ini setting can be set to true/false.

The default is '1' according to the documentation. However, you might want to check the inverse, that it isn't off:
!= FALSE or !empty()
if (ini_get('display_errors') != FALSE))
{
// show debug info
}
else
{
// show just "oops!"
}
Or as Anthony pointed out, you could just check for 1
if(ini_get('display_errors') == 1))
You might also want to check error_reporting, as it is another common setting that is used to control the displaying of errors, although its meaning is slightly different than display_errors
if(error_reporting() != 0)

Related

How to override the NQPMatch.Str function

... Or how to change $<sigil>.Str value from token sigil { ... } idependently from the matched text. Yes I'm asking how to cheat grammars above (i.e. calling) me.
I am trying to write a Slang for Raku without sigil.
So I want the nogil token, matching anything <?> to return NqpMatch that stringifies: $<sigil>.Str to '$'.
Currently, my token sigil look like that
token sigil {
| <[$#%&]>
| <nogil> { say "Nogil returned: ", lk($/, 'nogil').Str; # Here It should print "$"
}
}
token nogil-proxy {
| '€'
| <?>
{log "No sigil:", get-stack; }
}
And the method with that should return a NQPMatch with method Str overwritten
method nogil {
my $cursor := self.nogil-proxy;
# .. This si where Nqp expertise would be nice
say "string is:", $cursor.Str; # here also it should print "$"
return $cursor;
}
Failed try:
$cursor.^cache_add('Str', sub { return '$'; } );
$cursor.^publish_method_cache;
for $cursor.^attributes { .name.say };
for $cursor.^methods { .name.say };
say $cursor.WHAT.Str;
nqp::setmethcacheauth($cursor, 0);
Currently, most of my tests work but I have problems in declarations without my (with no strict) like my-var = 42; because they are considered as method call.
#Arne-Sommer already made a post and an article. This is closely related. But this questions aims:
How can we customize the return value of a compile-time token and not how to declare it.
Intro: The answer, pointed by #JonathanWorthington:
Brief: Use the mixin meta function. (And NOT the but requiring compose method.)
Demo:
Create a NQPMatch object by retrieving another token: here the token sigil-my called by self.sigil-my.
Use ^mixin with a role
method sigil { return self.sigil-my.^mixin(Nogil::StrGil); }
Context: full reproducible code:
So you can see what type are sigil-my and Nogil::StrGil. But I told you: token (more than method) and role (uninstantiable classes).
role Nogil::StrGil {
method Str() {
return sigilize(callsame);
}
}
sub EXPORT(|) {
# Save: main raku grammar
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');
role Nogil::NogilGrammar {
method sigil {
return self.sigil-my.^mixin(Nogil::StrGil);
}
}
token sigil-my { | <[$#%&]> | <?> }
# Mix
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);
# Return empty hash -> specify that we’re not exporting anything extra
return {};
}
Note: This opens the door to mush more problems (also pointed by jnthn question comments) -> -0fun !

Apache AuthzSendUnauthorizedOnFailure?

I was wondering if I can force apache to send HTTP 401 instead of HTTP 403 in case any condition inside RequireAll fails.
Surprisingly I found AuthzSendForbiddenOnFailure, which forces 403 instead of 401. But what about opposite?
How I can force apache reask for the login and password in case authorization fails?
Edit:
I looked at the debug log right now.
The thing is that if I will put just Require valid user in the RequireAll section, in the log I would see "denied (no authentocated user yet)". Yet if I will put Require env SMTH additionally, apache will check Require valid user but then, after it will fail with "denied (no authentocated user yet)", it will also check my second Require and will fail just with "denied" and throw HTTP 403. I think this is a bug. Why apache checks for a second Require in RequireAll if the first one failed already?
Edit2:
It seems that it wasn't implemented yet:
https://github.com/apache/httpd/blob/trunk/modules/aaa/mod_authz_core.c#766
if (child_result != AUTHZ_NEUTRAL) {
/*
* Handling of AUTHZ_DENIED/AUTHZ_DENIED_NO_USER: Return
* AUTHZ_DENIED_NO_USER if providing a user may change the
* result, AUTHZ_DENIED otherwise.
*/
if (section->op == AUTHZ_LOGIC_AND) {
if (child_result == AUTHZ_DENIED) {
auth_result = child_result;
break;
}
if ((child_result == AUTHZ_DENIED_NO_USER
&& auth_result != AUTHZ_DENIED)
|| (auth_result == AUTHZ_NEUTRAL)) {
auth_result = child_result;
}
}
else {
/* AUTHZ_LOGIC_OR */
if (child_result == AUTHZ_GRANTED) {
auth_result = child_result;
break;
}
if ((child_result == AUTHZ_DENIED_NO_USER
&& auth_result == AUTHZ_DENIED)
|| (auth_result == AUTHZ_NEUTRAL)) {
auth_result = child_result;
}
}
}

Make Scrapy send POST data from Javascript function

I'm playing with Scrapy and playing with this tutorial. Things look good but I noticed Steam changed their age check so there is no longer a form in DOM. So the suggested solution will not work:
form = response.css('#agegate_box form')
action = form.xpath('#action').extract_first()
name = form.xpath('input/#name').extract_first()
value = form.xpath('input/#value').extract_first()
formdata = {
name: value,
'ageDay': '1',
'ageMonth': '1',
'ageYear': '1955'
}
yield FormRequest(
url=action,
method='POST',
formdata=formdata,
callback=self.parse_product
)
Checking an example game that forces age check; I noticed the View Page button is no longer a form:
<a class="btnv6_blue_hoverfade btn_medium" href="#" onclick="ViewProductPage()"><span>View Page</span></a>
And the function being called will eventually call this one:
function CheckAgeGateSubmit( callbackFunc )
{
if ( $J('#ageYear').val() == 2019 )
{
ShowAlertDialog( '', 'Please enter a valid date' );
return false;
}
$J.post(
'https://store.steampowered.com/agecheckset/' + "app" + '/9200/',
{
sessionid: g_sessionID,
ageDay: $J('#ageDay').val(),
ageMonth: $J('#ageMonth').val(),
ageYear: $J('#ageYear').val()
}
).done( function( response ) {
switch ( response.success )
{
case 1:
callbackFunc();
break;
case 24:
top.location.reload();
break;
case 15:
case 2:
ShowAlertDialog( 'Error', 'There was a problem verifying your age. Please try again later.' );
break;
}
} );
}
So basically this is making a POST with some data...what would be the best way to do this in Scrapy, since this is not a form any longer? I'm just thinking on ignoring the code where the form is obtained and simply send the request with the FormRequest object...but is this the way to go? An alternative could also be setting cookies for age and pass it on every single request so possibly the age check is ignored altogether?
Thanks!
You should probably just set an appropriate cookie and you'll be let right through!
If you take a look at what your browser has when entering the page:
and replicate that in scrapy:
cookies = {
'wants_mature_content':'1',
'birthtime':'189302401',
'lastagecheckage': '1-January-1976',
}
url = 'https://store.steampowered.com/app/9200/RAGE/'
Request(url, cookies)
lastagecheckage should probably be enough on it's own but I haven't tested it.

Perl6: check if STDIN has data

In my Perl 6 script, I want to do a (preferably non-blocking) check of standard input to see if data is available. If this is the case, then I want to process it, otherwise I want to do other stuff.
Example (consumer.p6):
#!/usr/bin/perl6
use v6.b;
use fatal;
sub MAIN() returns UInt:D {
while !$*IN.eof {
if some_fancy_check_for_STDIN() { #TODO: this needs to be done.
for $*IN.lines -> $line {
say "Process '$line'";
}
}
say "Do something Else.";
}
say "I'm done.";
return 0;
}
As a STDIN-Generator I wrote another Perl6 script (producer.p6):
#!/usr/bin/perl6
use v6.b;
use fatal;
sub MAIN() returns UInt:D {
$*OUT.say("aaaa aaa");
sleep-until now+2;
$*OUT.say("nbbasdf");
sleep-until now+2;
$*OUT.say("xxxxx");
sleep-until now+2;
return 0;
}
If consumer.p6 works as expected, it should produce the following output, if called via ./producer.p6 | ./consumer.p6:
Process 'aaaa aaa'
Do something Else.
Process 'nbbasdf'
Do something Else.
Process 'xxxxx'
Do something Else.
I'm done.
But actually, it produces the following output (if the if condition is commented out):
Process 'aaaa aaa'
Process 'nbbasdf'
Process 'xxxxx'
Do something Else.
I'm done.
You are using an old version of Perl 6, as v6.b is from before the official release of the language.
So some of what I have below may need a newer version to work.
Also why are you using sleep-until now+2 instead of sleep 2?
One way to do this is to turn the .lines into a Channel, then you can use .poll.
#!/usr/bin/env perl6
use v6.c;
sub MAIN () {
# convert it into a Channel so we can poll it
my $lines = $*IN.Supply.lines.Channel;
my $running = True;
$lines.closed.then: {$running = False}
while $running {
with $lines.poll() -> $line {
say "Process '$line'";
}
say "Do something Else.";
sleep ½;
}
say "I'm done.";
}
Note that the code above blocks at the my $lines = … line currently; so it doesn't start doing something until the first line comes in. To get around that you could do the following
my $lines = supply {
# unblock the $*IN.Supply.lines call
whenever start $*IN.Supply {
whenever .lines { .emit }
}
}.Channel;

PHP InstanceOf works locally but not on host server

I have an issue with PHP 7's instanceof statement that is only happening on certain conditions.
It seems that instanceof works locally on my dev machine (MAMP Pro running PHP 7.0.13) but not on my Hosted Server (HostEurope, PHP 7).
I have tried the following :
downgrading to PHP 5.6
using is_a instead
Using fully qualified name e.g. \Site\Ad
but they all exhibit the same behaviour.
I've tried Googling "PHP instanceof not working" and variations of it but I haven't found anything relevant.
I was wondering if anyone had experienced something similar or possible solutions to try?
The Code in question is:
<?php
namespace Site;
require_once(__DIR__."/../interface/IOutput.php");
require_once(__DIR__."/../lib/Lib.php");
require_once(__DIR__."/../site/AdMediumRectangle.php");
require_once(__DIR__."/../site/AdSnapBanner.php");
require_once(__DIR__."/../const/Const.php");
class AdFactory
{
/**
* Define(AD_BANNER, 0);
* Define(AD_RECTANGE, 1);
* Define(AD_SUPERBANNER, 2);
* Define(AD_SKYSCRAPER, 3);
**/
/**
* #param $object
* #return AdMediumRectangle|AdSnapBanner|string
*/
public static function CreateObject($object)
{
$ad = wire(pages)->get("/ads/")->children->getRandom();
if ($ad == null)
return new \Exception("No Random Ad found");
switch ($object) {
case AD_BANNER:
echo "AD_Banner Selected\r\n";
$adSnapBanner = new AdSnapBanner($ad);
return $adSnapBanner;
break;
case AD_RECTANGLE:
echo "AD Rectangle Created\r\n";
$adRectangle = new AdMediumRectangle($ad);
return $adRectangle;
break;
case AD_SUPERBANNER:
case AD_SKYSCRAPER:
default:
echo "AdFactory BlankObject created";
return "";
break;
}
}
public static function Markup($object)
{
$obj = AdFactory::CreateObject($object);
if (($obj instanceof AdSnapBanner) || ($obj instanceof AdMediumRectangle)) {
echo "InstanceOf worked";
return $obj->Markup();
}
else {
echo "return blankString";
return "";
}
}
}
Update : This is the code that calls the above AdFactory class
<?php
namespace Site;
require_once(__DIR__."/../interface/IOutput.php");
require_once(__DIR__."/../lib/Lib.php");
require_once(__DIR__."/../factory/AdFactory.php");
require_once (__DIR__."/../const/Const.php");
class AdInjector
{
public static function Inject($page, $ad_pos)
{
//Select an Ad from /Ads/ according to criteria
//$ads = wire(pages)->get("/ads/")->children;
$count = 1; //$ads->count();
if ($count > 0) {
$mod = $page->id % 3;
echo "mod=" . $mod . "\r\n";
if ($mod == $ad_pos) {
switch ($mod) {
case AD_POS_TITLE;
case AD_POS_BANNER:
//Pick an Snap Banner
echo "Banner Injected (banner):" . AD_BANNER . "\r\n";
return AdFactory::Markup(AD_BANNER);
break;
case AD_POS_SIBLINGS:
echo "Banner Injected (rect):" . AD_RECTANGLE . "\r\n";
//Pick an Ad Rectangle
return AdFactory::Markup(AD_RECTANGLE);
break;
default:
return "";
break;
}
} else
return "";
} else
return "";
}
}
instanceof is a language construct which is so essential to PHP that it is de facto impossible not to work properly.
The code you provided is not enough to tell where the issue might be happening.
Chances are, you have a folder not readable on your online server and simply get somewhere a null value instead of an expected object along your code. Ask yourself: "If it is not the object I expect, what else is it?"
Use var_dump() or printf() to investigate what your variables actually contain and you will find the error soon.
For your code, PHPUnit tests would be a benefit, or at least the use of assert() here and there in your code.
Turns out there was a bug in 1 of the API calls I was making to the Processwire CMS.
$ad = wire(pages)->get("/ads/")->children->getRandom();
And my local and server instance of Processwire was not the same version, which was news to me. I normally have it synchronised, including any modules I use.
I also suspect my null check is not correct PHP, to add to the problem.
It has to do with namespaces used in the code:
Locally (Code with no namespaces) I used this, working fine:
if ($xmlornot instanceof SimpleXMLElement) { }
But on the server (code with namespaces) only this worked:
if ($xmlornot instanceof \SimpleXMLElement) { }
See also this question/answer: instanceof operator returns false for true condition