For quite a while now we experience a very weird problem with our hosting server. Once a while (seems randomly) variables in PHP become NULLs.
In general everything works perfectly fine, but once a while it happens. All accounts on the server are affected and all PHP apps (including PHPMyAdmin, Wordpress our own scripts). We contacted our hosting company, but they are unable to find any solution.
I had few ideas, the most promising one was an issue with Suhosin. But I do not get any message in the log directly from it.
We made a simplest possible script to reproduce the error:
<?php
class Example
{
protected $stringVar = 'this is a string value';
public function accessParameter()
{
$error = false;
if (isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : " . $this->toStringWithType($this->stringVar) . "\n";
} else {
echo "string var is not set\n";
$error = true;
}
if ($error) {
$logfile = dirname(__FILE__)."/random_bug_log.log";
file_put_contents($logfile, date('Y-m-d H:i:s')."\n", FILE_APPEND);
file_put_contents($logfile, $this->toStringWithType($this->stringVar) . "\n", FILE_APPEND);
}
}
public function toStringWithType($var)
{
$type = gettype($var);
return "($type) '$var'";
}
}
$e = new Example();
$e->accessParameter();
Normal output:
string var : (string) 'this is a string value'
Output when the weird thing happens:
string var is not set
I open to any ideas or suggestions how to solve this problem. I guess the ultimate solution is to change the hosting company. I did not manage to create this issue on localhost or any other server.
Test piece that have been made, including your suggestions:
<?php
class Example
{
protected $stringVar = 'this is a string value';
public function accessParameter() {
$error = false;
if(isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : "
.$this->toStringWithType($this->stringVar)
."\n";
} else {
echo "string var is not set\n";
$error = true;
}
if($error) {
$logfile = dirname(__FILE__)."/random_bug_log.log";
file_put_contents($logfile, date('Y-m-d H:i:s')." ", FILE_APPEND);
file_put_contents($logfile,
$this->toStringWithType($this->stringVar) . "\n",
FILE_APPEND);
}
}
public function writeParameter() {
$this->stringVar="variable assigned";
if(isset($this->stringVar) && !is_null($this->stringVar)) {
echo "string var : "
.$this->toStringWithType($this->stringVar)
."\n";
} else {
echo "string var is not set\n";
$error = true;
}
}
public function toStringWithType($var)
{
$type = gettype($var);
return "($type) '$var'";
}
}
$e = new Example();
$e->accessParameter();
$e->writeParameter();
The output while the thing happens:
string var is not set
string var is not set
it is very strange problem.
it may not be a solution but worth to try;
protected $stringVar;
function __construct() {
$this->stringVar = 'this is a string value';
}
I would recommend to use !== instead of is_null to see if the variable is actually null.
if (isset($this->stringVar) && ($this->stringVar !== null)) {
or
if (isset($this->stringVar) && (!empty($this->stringVar)) {
should do the work too.
In case of theses type of issues check with the value that you have in if condition and do what you want in else. Like in your situation do like:
if(isset($this->stringVar) && ($this->stringVar == "this is a string value")) {
}else{
// your code here...
}
Related
I'm looking for a way to include or require the content of a variable, instead of a file.
Normally, one can require/include a php function file with either of these:
require_once('my1stphpfunctionfile.php')
include('my2ndphpfunctionfile.php');
Suppose I wanted to do something like this:
$contentOf1stFFile = file_get_contents('/tmp/my1stphpfunctionfile.php');
$contentOf2ndFFile = file_get_contents('/tmp/my2ndphpfunctionfile.php');
require_once($contentOf1stFFile);
require_once($contentOf2ndFFile);
Now, in the above example, I have the actual function files which I am loading into variables. In the real world scenario I'm actually dealing with, the php code in the function files are not stored in files. They're in variables. So I'm looking for a way to treat those variables as include/require treats the function files.
I'm new to php so please forgive these questions if you find them foolish. What I'm attempting to do here does not appear to be possible. What I ended up doing was using eval which I'm told is very dangerous and should be avoided:
eval("?>$contentOf1stFFile");
eval("?>$contentOf2ndFFile");
Content of $contentOf1stFFile:
# class_lookup.php
<?php
class Lookup_whois {
// Domain name which we want to lookup
var $domain;
// TLD for above domain, eg. 'com', 'net', etc...
var $tld;
// Array which contains information needed to parse the whois server response
var $tld_params;
// Sets to error code if something fails
var $error_code;
// Sets user-friendly error message if something goes wrong
var $error_message;
// For internal use mainly - raw response from the whois server
var $whois_raw_output;
function Lookup_whois($domain, $tld, $tld_params) {
$this->domain = $domain;
$this->tld = $tld;
$this->tld_params = $tld_params;
}
function check_domain_spelling() {
if (preg_match("/^([A-Za-z0-9]+(\-?[A-za-z0-9]*)){2,63}$/", $this->domain)) {
return true;
} else {
return false;
}
}
function get_whois_output() {
if (isset($this->tld_params[$this->tld]['parameter'])) {
$query = $this->tld_params[$this->tld]['parameter'].$this->domain.'.'.$this->tld;
} else {
$query = $this->domain.'.'.$this->tld;
}
$server = $this->tld_params[$this->tld]['whois'];
if (!$this->check_domain_spelling()) {
$this->error_message = 'Domain name is not correct, check spelling. Only numbers, letters and hyphens are allowed';
return false;
}
if (!$server) {
$this->error_message = 'Whois server name is empty, please check the config file';
return false;
}
$output = array();
$fp = fsockopen($server, 43, $errno, $errstr, 30);
if(!$fp) {
$this->error_code = $errno;
$this->error_message = $errstr;
fclose($fp);
return false;
} else {
sleep(2);
fputs($fp, $query . "\n");
while(!feof($fp)) {
$output[] = fgets($fp, 128);
}
fclose($fp);
$this->whois_raw_output = $output;
return true;
}
}
function parse_whois_data() {
if (!is_array($this->whois_raw_output) && Count($this->whois_raw_output) < 1) {
$this->error_message = 'No output to parse... Get data first';
return false;
}
$wait_for = 0;
$result = array();
$result['domain'] = $this->domain.'.'.$this->tld;
foreach ($this->whois_raw_output as $line) {
#if (ereg($this->tld_params[$this->tld]['wait_for'], $line)) {
if (preg_match($this->tld_params[$this->tld]['wait_for'],$line)) {
$wait_for = 1;
}
if ($wait_for == 1) {
foreach ($this->tld_params[$this->tld]['info'] as $key => $value) {
$regs = '';
if (ereg($value.'(.*)', $line, $regs)) {
if (key_exists($key, $result)) {
if (!is_array($result[$key])) {
$result[$key] = array($result[$key]);
}
$result[$key][] = trim($regs[1]);
} else {
$result[$key] = trim($regs[1]);
$i = 1;
}
}
}
}
}
return $result;
}
}
?>
Are there any other alternatives?
No there are no other alternatives.
In terms of security there is no difference if you include() a file or eval() the content. It depends on the context. As long as you only run your own code there is nothing "dangerous".
I have created a function as follows:
//function for first name field
function name ($fname) {
//validate to see if field is empty
if (empty($fname)) {
return (false);
}
$welcome_string = '<p> Welcome ' . $fname . '. We\'re glad you\'re here! Take a look around!</p>';
return $welcome_string;
}//end fname function
When the function passes the check I echo the function and get the welcome_string. However, I need to display an error outside of the function when it returns false. I cannot figure out how to do this. Below is the code where I call the function:
echo name($fname);
What you want to do is add a check for that:
$result = name($fname);
if ($result) {
echo $result;
} else {
echo "There was an error.";
}
Using a ternary if, you can do this in shorthand:
$result = name($fname);
echo $result ? $result : "There was an error.";
Or even shorter without introducing a new variable:
echo name($fname) ?: "There was an error.";
You could simply do:
$result = name($fname);
echo $result?$result:"error message";
<?php
function greeting($name)
{
if (empty($name))
return false;
$welcome_string = 'Welcome ' . $name . ". We're glad you're here! Take a look around!\n";
return $welcome_string;
}
foreach(['Rita', 'Sue', '', null, 0, '0'] as $name)
echo ($message = greeting($name))
? $message
: "Who are you?\n";
Output:
Welcome Rita. We're glad you're here! Take a look around!
Welcome Sue. We're glad you're here! Take a look around!
Who are you?
Who are you?
Who are you?
Who are you?
Why strpos PHP not work with fsockopen response ?
When load this code. This code will be requests sdgsgsdgsfsdfsd.ca to whois.cira.ca server and find text Domain status: available with strpos PHP if found it's will be echo
{"domain":"sdgsgsdgsfsdfsdca","availability":"available"}
but if not found text. It's will be echo
{"domain":"sdgsgsdgsfsdfsdca","availability":"TAKEN"}
In this case found text but still echo
{"domain":"sdgsgsdgsfsdfsdca","availability":"TAKEN"}
How can i do ?
<?php
$server = "whois.cira.ca";
$response = "Domain status: available";
showDomainResult(sdgsgsdgsfsdfsd.ca,$server,$response);
function checkDomain($domain_check,$server,$findText)
{
$con = fsockopen($server, 43);
if (!$con) return false;
fputs($con, $domain_check."\r\n");
$response = ' :';
while(!feof($con))
{
$response .= fgets($con,128);
}
echo $response."<BR><BR><BR><BR><BR>";
fclose($con);
if (strpos($response, $findText))
{
return true;
}
else
{
return false;
}
}
function showDomainResult($domain_check,$server,$findText)
{
if (checkDomain($domain_check,$server,$findText))
{
class Emp
{
public $domain = "";
public $availability = "";
}
$e = new Emp();
$e->domain = $domain_check;
$e->availability = "available";
echo json_encode($e);
}
else
{
class Emp
{
public $domain = "";
public $availability = "";
}
$e = new Emp();
$e->domain = $domain_check;
$e->availability = "TAKEN";
echo json_encode($e);
}
}
?>
you're using strpos wrong, if the string START with what you're searching for, it will return int(0), which is "kinda false" by PHP's definition. explicitly check for false, like this
return false!==strpos($response, $findText);
and make sure you're using !== not !=
and as a rule of thumb, never use loose comparison operators in PHP if you can avoid it, hilarious bugs can occur if you do: https://3v4l.org/tT4l8
I am new to PHP, so I apologize if this looks like a mess... I am trying to validate a form using the following three functions - checkName, checkEmail, and checkMessage. The problem I am running into is when I submit the form, it always displays the first error, even if the input is correct. Can anyone tell me what I'm doing wrong?
function checkName(){
if($name == ''){
print "Please enter your name!<br />";
return false;
}
else{
if(strlen($name)<2) {
print "Your name should be more than 1 characters long!<br />";
return false;
}
else{
return true;
}
}
}
function checkEmail(){
if($from == '') {
print "Please enter your email address!<br />";
return false;
}
else{
if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $from)){
print "Please enter a valid email address!<br />";
return false;
}
else{
return true;
}
}
}
function checkMessage(){
if($message == '') {
print "Please enter your message!<br />";
return false;
}
else{
if(strlen($message)<10) {
print "Your message should be more than 10 characters long!<br />";
return false;
}
else{
return true;
}
}
}
if($validation == ''){
$a = checkName();
$b = checkEmail();
$c = checkMessage();
$result = array($a, $b, $c);
return $result;
Pass the variables to test into your functions to check them. The way you have it now, it would assume you are using global variables for $name,$message,$email. That would require the use of the global keyword (or some other options) in the functions, but is considered poor practice. Best to pass the variables
Called as:
$a = checkName($name);
$b = checkEmail($email);
$c = checkMessage($message);
Definitions
// Pass variable to function
function checkName($name){
if($name == ''){
print "Please enter your name!<br />";
return false;
}
else{
if(strlen($name)<2) {
print "Your name should be more than 1 characters long!<br />";
return false;
}
else{
return true;
}
}
}
function checkEmail($email){
// etc...
}
function checkMessage($message){
// etc...
}
By the way, as someone who frequently has to maintain old PHP code written by others, I can tell you that it is highly recommended that you do not use variable names like $a,$b,$c. Instead make them readable like $nameResult, $emailResult, $messgeResult.
In the functions your variables are not defined. If they are defined at all you have to use global $variable in your functions to have them defined in your functions
example:
bad:
$var = 'Hello';
function fun () {return $var;}
echo fun () . ' world';
good:
$var = 'Hello';
function fun () {
global $var;
return $var;
}
echo fun () . ' world';
I have been trying to write a class to be used for displaying errors and error log.
class CError {
//Error Logging
var $Log;
public function Log($Comment, $Detail = ""){
$Log .= $Comment . "\n";
if ($Detail !== ""){
$Log .= "--" . $Detail . "--\n";
}
}
public function Clear_Log(){
$Log = "";
}
public function Display_Log(){
echo $this->Log;
}
//Error Display
var $ErrorCode = array(
0 => "0: No Error Code found, so either you got here by some rogue code or ...",
1 => "1: General Error, if you are here something went wrong",
2 => "2: Invalid information provided",
3 => "3: Alternate path taken, check message for details",
42 => "42: Here is your answer, but do you know the question?",
50 => "50: You messed with the Creepers without your Diamond Sword, didn't you",
9001 => "9001: Its over 9000... or more likely a value used was to large",
418 => "418: I'm a Teapot, found the error that drove you crazy"
);
public function Error($Error = 0, $ShowLog = false){
if ($Error === ""){
$Error = 0;
}
foreach ($ErrorCode as $key => $value){
if($key == $Error){
echo "<h3 style='color:red'>" . $value . "</h3><br />";
}
}
if($ShowLog == true){
echo $this->Log;
}
}
}
This is how I use the error class
include 'CError.php';
$Error = new CError;
$Error->Log("Email is Required");
$Error->Display_Log();
$Error->Error(2,true);
The problem is, nothing is displayed when used. It is skipped I think but not sure. I do not have access to the error logs for the server so I do not know if an error is being produced or not but the code will run through to the exit points in my main code(irrelevant to the class)
--EDIT--
The answers that tell to change $Log with $this->Log has fixed the issue with the $Log variable. It still has not fixed the issue with the error code array being displayed in the foreach loop.
--EDIT--
I solved the issue by adding $this->ErrorCode to the foreach loop.
You need to access class variable like $this->Log() in Log and Clear_Log() functions.
Try:
public function Log($Comment, $Detail = ""){
$this->Log .= $Comment . "\n";
if ($Detail !== ""){
$this->Log .= "--" . $Detail . "--\n";
}
}
public function Clear_Log(){
$this->Log = "";
}
You should modify $this->Log in methods Log and Clear_Log, like you access it in Display_Log. And you just access a local variable.
you're using the name Log for both function as well as variable. try changing the name for any one.