I'm relatively new in programming. I'm trying to catch and display errors in my aplication. With global variable is simple:
$errors = '';
class Name {
/**
* Validate form
*/
public function validate_form() {
global $errors;
(...)
if ( empty($_POST["blabla"]) ) {
$errors = 'Error';
}
(...)
return;
}
/**
* Display errors
*/
public function show_error() {
global $errors;
if(!empty($errors)) return '<div class="error">' . PHP_EOL . htmlspecialchars($errors) .'</div>';
}
}
...but i read that you should not use global variables. How can i do the same thing without global variable?
Sorry for my english ;)
How about not making it global, ie:
<?php
class Name {
public $errors;
/*
* Validate form
*/
public function validate_form() {
(...)
if ( empty($_POST["blabla"]) ) {
$this->errors = 'Error';
}
(...)
return;
}
}
Then everytime you run a fucntion in that class, check if an error was generated:
$obj = new Name()->validate_form();
if(isset($obj->errors)){
//oops, an error occured, do something
}
You can throw Exceptions
<?php
class Name {
/**
* Validate form
*/
public function validate_form() {
(...)
if ( empty($_POST["blabla"]) ) {
throw new RuntimeException( 'Error' );
}
(...)
return;
}
$obj = new Name();
/**
* Display errors
*/
public function show_error($e) {
return '<div class="error">' . PHP_EOL . htmlspecialchars($e->getMessage()) .'</div>';
}
}
// TEST
try {
$obj->validate_form();
}
catch(Exception $e) {
$obj->show_error($e);
}
Related
I have a class called members, i have an example below. What i am asking is how do i set the values of title. So for example , i only allow Mr, Mrs, Miss and any other values will throw out an error stating Only Mr,Mrs,Miss is allowed , Firstname must be John..
class Member
{
private $title;
private $firstname;
public function __construct( $title )
{
$this->title = $title;
}
public function showProfile()
{
echo "<dl>";
echo "<dt>Title:</dt><dd>$this->title</dd>";
echo "</dl>";
}
}
$data = new Member( "Mrr" );
$data->showProfile();
You can try this , hope this will be helpful.
Try this code snippet here
<?php
ini_set("display_errors", 1);
class Member
{
private $title;
public function __construct($title)
{
if(!in_array($title, ["Mr","Mrs","Miss"]))
{
throw new Exception("Only Mr,Mrs,Miss are allowed!");
//or you can simple echo out your message instead of exception
}
$this->title = $title;
}
public function showProfile()
{
echo "<dl>";
echo "<dt>Title:</dt><dd>$this->title</dd>";
echo "</dl>";
}
}
$data = new Member("Mrr");
Optionally you can set a variable for this error with in the class, which prevent further execution of methods of class script. You can also do it like this
Solution 2:
Try this code snippet here
<?php
ini_set("display_errors", 1);
class Member
{
private $title;
private $error=false;
public function __construct($title)
{
if(!in_array($title, ["Mr","Mrs","Miss"]))
{
$this->error=true;
}
$this->title = $title;
}
public function showProfile()
{
if($this->error!==true)
{
echo "<dl>";
echo "<dt>Title:</dt><dd>$this->title</dd>";
echo "</dl>";
}
else
{
echo "Only Mr,Mrs,Miss is allowed!";
}
}
}
$data = new Member("Mrr");
$data->showProfile();
Make a setter
function setTitle($newTitle){
if(in_array($newTitle, array('Mr', 'Miss', 'Mrs' ))
$this->title=$newTitle;
else
echo 'ERROR';
}
And then call it from the constructor
I didnt like any of the answers.
Here's mine. I think you should use a mutator in your solution. The member class should be decoupled from the setter.
class Member
{
private $title;
public function setTitle($title)
{
$this->title = $title;
}
public function showProfile()
{
return sprintf("<dl><dt>Title</dt><dt><dd>%s</dd></dt></dl>" , $this->title );
}
}
class TitleProperty
{
protected $name = 'title';
protected $allowed_allowed = ['mr', 'mrs', 'miss'];
public $errors = [];
/**
*#param Member $member
*#param string $value
*/
public function __construct( Member $member, $value )
{
if(!in_array($value, $this->allowed_allowed )){
$this->errors[] = "Only Mr,Mrs,Miss is allowed";
}
else{
$member->setTitle( $value );
}
}
}
$member = new Member();
$property = new TitleProperty($member, 'hello');
if($property->errors){
print_r($property->errors);
}
else{
echo 'title set.';
}
There you go
Similar question has been asked few days ago about error handling. People explained to me how to get errors from class. And i understand it how to create error names and validate in __construct section but still struggling with multiple functions
class magic
{
/**
* #param string $name
* #param string $surname
* #param int $age
* #throws Exception
*/
public function __construct($name, $surname, $age)
{
$errors = [];
if (empty($name)) {
$errors[] = 'Name is required.';
}
if (empty($surname)) {
$errors[] = 'Surname is required.';
}
if (!empty($errors)) {
throw new Exception(implode('<br />', $errors));
}
$this->name = $name;
$this->surname = $surname;
$this->age = $age;
}
public function printFullname()
{
echo $this->name . ' ' . $this->surname;
}
}
another file:
include 'class.php';
try {
$test = new magic('', '', '33');
$test->printFullname();
} catch (Exception $exc) {
echo $exc->getMessage(); //error messages
}
It works but problem with another function in this class:
class magic
{
/**
* #param string $name
* #param string $surname
* #param int $age
* #throws Exception
*/
public function __construct($name, $surname, $age)
{
$errors = [];
if (empty($name)) {
$errors[] = 'Name is required.';
}
if (empty($surname)) {
$errors[] = 'Surname is required.';
}
if (!empty($errors)) {
throw new Exception(implode('<br />', $errors));
}
$this->name = $name;
$this->surname = $surname;
$this->age = $age;
}
public function printFullname()
{
echo $this->name . ' ' . $this->surname;
}
public function auth()
{
//authentication goes here
if...
$errors[] = 'Error1';
else
$errors[] = 'Error2';
etc...
}
}
another file:
include 'class.php';
try {
$test = new magic('', '', '33');
$test->auth();
} catch (Exception $exc) {
echo $exc->getMessage(); //error messages
}
My function auth() working and return errors as if then echo but i would like to do with array.
I think what you are doing is unnecessary.
By the way you've written the constructor parameters, you are automatically saying that those parameters are required and must not be empty, since you haven't set a default value for them.
As for errors in multiple functions, I'd suggest you to look up at custom Exceptions. Create a custom Exception for every specific error (if you need to apply different actions or different types of errors) and then catch them as you would do with an Exception.
If you want to get errors from the exception as an array you should create your own exception class:
class MagicException extends Exception
{
private $errors;
function __construct($message, array $errors, $code = 0, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
$this->errors = $errors;
}
function getErrors()
{
return $this->errors;
}
}
Usage:
try {
$errors = [];
// some code..
$errors[] = 'Example error';
if ($errors) {
throw new MagicException('Something went wrong', $errors);
}
} catch (MagicException $e) {
// #todo: handle the exception
print_r($e->getErrors());
}
Output:
Array
(
[0] => Example error
)
So I want to make a function to display errors instead of saying echo "error message", I want something like $this->errorDisplay('error message');
I currently have this, but it's not doing the job.
function errorDisplay($msg) {
$this->errors[] = $msg;
foreach($this->errors as $error) {
echo $error;
}
}
public function checkFields($username,$password) {
if(!empty($username) && !empty($password)) {
//proceed to validation
} else {
$this->errorDisplay('All fields are required.');
}
}
Instead of trying to do everything in one method, split the process into 2. One method adds messages to an array, and the other shows all the previously saved up messages.
Class xxx
{
public $errors = array();
public function addError($msg) {
$this->errors[] = $msg;
}
public function showErrors() {
foreach($this->errors as $error) {
echo $error;
}
}
public function initErrors() {
$this->errors = array();
}
public function checkFields($username,$password) {
$this->initErrors();
if( empty($username) ) {
$this-addError('Username missing');
}
if ( empty($password) ) {
$this-addError('Password missing');
}
if ( count($this->errors) > 0 ) {
$this->showErrors();
}
}
} //end class
I was trying to use a inherited model, by creating a model in core/ folder, and create a newer model that extends the model in core/ folder, but then, when I try to log in, I get this error:
Severity: Notice
Message: Undefined property: CL_Login::$M_Login
Filename: controllers/CL_Login.php
Line Number: 47
The form is showed correctly, and posts to the following controller CL_Login/VerifyLogin.
I have created the following controller:
public function VerifyLogin()
{
$this->form_validation->set_rules('InputUsername', 'Username', 'required');
$this->form_validation->set_rules('InputPassword', 'Password', 'required|callback_CheckPassword');
if ($this->form_validation->run())
{
echo 'login sukses';
}
else
{
echo 'login gagal';
}
}
public function CheckPassword()
{
$output = $this->M_Login->get_login($this->input->post('InputUsername'),$this->input->post('InputPassword'));
print_r($output);
// if($output)
// {
// return true;
// }
// else
// {
// return false;
// }
}
And here's the model inside Model folder:
class M_Login extends MY_Model {
protected $table = 'ms_user';
protected $primary_key = 'user_id';
public function __construct()
{
parent::__construct();
}
public function get_login($query = NULL, $username, $password)
{
$query['where']['user_name'] = $username;
$query['where']['user_password'] = md5($password);
return $this->get($query);
}
}
And here's the model inside core folder:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Master model of SimplaCMS
*
* #author Akbar Syarif
* #email aksa.uncp#gmail.com
* #package SimplaCMS
*/
class MY_Model extends CI_Model {
// table
protected $table;
// primary key
protected $primary_key;
// error status
protected $error = FALSE;
// error message
protected $error_message = array();
public function __construct()
{
parent::__construct();
}
/**
* Add custom data to table
*
* #param Array (data)
* #return boolen. true if data successfully save and false if error occured
*/
public function insert( $data = NULL )
{
// if data not set
if ( is_null($data) ) {
$this->error = TRUE;
throw new Exception("The first parameter cannot be empty");
}
// if data not array
if ( ! is_array($data) ) {
$this->error = TRUE;
throw new Exception("The first parameter must be an array");
}
if ( ! $this->error ) {
$this->db->insert($this->table, $data);
} else {
return FALSE;
}
}
public function insert_batch( $data = NULL )
{
// if data not set
if ( is_null($data) ) {
$this->error = TRUE;
throw new Exception("The first parameter cannot be empty");
}
// if data not array
if ( ! is_array($data) ) {
$this->error = TRUE;
throw new Exception("The first parameter must be an array");
}
if ( ! $this->error ) {
$this->db->insert_batch($this->table, $data);
} else {
return FALSE;
}
}
/**
* Get row
* #param Array (data)
* #return mixed. return false if nothing row found,
* return object if there's at least one row found
*/
private function _get( $query = NULL )
{
if(isset($query['select'])) $this->db->select($query['select']);
if(isset($query['where'])) $this->db->where($query['where']);
if(isset($query['where_no_escaped'])) $this->db->where($query['where_no_escaped'], NULL, FALSE);
if(isset($query['or_where'])) $this->db->or_where($query['or_where']);
if(isset($query['or_where_no_escaped'])) $this->db->or_where($query['or_where_no_escaped'], NULL, FALSE);
if(isset($query['like'])) $this->db->like($query['like']);
if(isset($query['order_by'])) $this->db->order_by($query['order_by']);
if(isset($query['limit'])) $this->db->limit($query['limit']);
if(isset($query['limit_offset'])) $this->db->limit($query['limit_offset'][0], $query['limit_offset'][1]);
// join table
if(isset($query['join'])) {
if ( ! is_array($query['join']) ) {
$this->error = TRUE;
throw new Exception("Join value must be an array");
} else {
foreach ($query['join'] as $key => $value) {
$this->db->join($value[0], $value[1], $value[2]);
}
}
}
// return result
if ( ! $this->error ) {
$result = $this->db->get($this->table);
} else {
$result = FALSE;
}
return $result;
}
public function get( $query = NULL )
{
$result = $this->_get($query)->result();
return $result;
}
public function row( $query = NULL )
{
$result = $this->_get($query)->row();
return $result;
}
public function count( $query = NULL )
{
$result = $this->_get($query)->num_rows();
return $result;
}
/**
* Delete row by primary key
* #param int. Primary Key
* #return boolean. return true if row successfully delete
*/
public function delete( $primary_key = NULL )
{
// if primary key not set
if ( is_null($primary_key) ) {
$this->error = TRUE;
throw new Exception("First parameter cannot be empty.");
}
// if nothing error
if ( ! $this->error ) {
$this->db
->where($this->primary_key, $primary_key)
->delete($this->table);
} else {
return FALSE;
}
}
/**
* Update row by primary key
* #param array. Custom data
* #param int. Primary Key
* #return boolen. return true if row successfully update
*/
public function update( $data, $primary_key )
{
// if first argument not set or not an array
if ( func_num_args() == 0 ) {
$this->error = TRUE;
throw new Exception("First parameter cannot be empty");
} else {
if ( ! is_array($data) ) {
$this->error = TRUE;
throw new Exception("First parameter must be an array");
}
}
// if second parameter not set
if ( func_num_args() == 0 ) {
$this->error = TRUE;
throw new Exception("First parameter cannot be empty");
}
// if nothing error
if ( ! $this->error ) {
$this->db
->set($data)
->where($this->primary_key, $primary_key)
->update($this->table);
} else {
return FALSE;
}
}
}
/* End of file MY_Model.php */
/* Location: ./application/models/MY_Model.php */
The controller receives the value from the textbox smoothly with no problem. However, I got the mentioned error above. What else should I check?
You have to ensure that you are loading the model which you can do in the your controllers constructor or in the method itself that is using it, by using $this->load->model('m_login');
And refer to it as ...
public function CheckPassword()
{
$output = $this->m_Login->get_login($this->input->post('InputUsername'),$this->input->post('InputPassword'));
print_r($output);
// More code here
}
See how that flies for you!
Hello I want to integrate the SEOStats Class with a project in codeigniter , is anyone provide me solution ?
I have tried to make the SEOstats class as a helper and load the helper in the specific controler , but a blank page is showing , I also try to include it via view but the same blank page i am seeing ,
I have included this code in my view file , the SEOstats directory also in the same views directory .
<?php
require_once 'SEOstats/bootstrap.php';
use \SEOstats\Services as SEOstats;
try {
$url = 'http://www.google.com/';
// Create a new SEOstats instance.
$seostats = new \SEOstats\SEOstats;
// Bind the URL to the current SEOstats instance.
if ($seostats->setUrl($url)) {
echo SEOstats\Alexa::getGlobalRank();
echo SEOstats\Google::getPageRank();
}
}
catch (SEOstatsException $e) {
die($e->getMessage());
}
i have also used it as library
<?php
namespace SEOstats;
use SEOstats\Common\SEOstatsException as E;
use SEOstats\Config as Config;
use SEOstats\Helper as Helper;
use SEOstats\Services as Service;
class SEOstats
{
const BUILD_NO = Config\Package::VERSION_CODE;
protected static $_url,
$_host,
$_lastHtml,
$_lastLoadedUrl
= false;
public function __construct($url = false)
{
if (false !== $url) {
self::setUrl($url);
}
}
public function Alexa()
{
return new Service\Alexa;
}
public function Google()
{
return new Service\Google;
}
public function OpenSiteExplorer()
{
return new Service\OpenSiteExplorer;
}
public function SEMRush()
{
return new Service\SemRush;
}
public function Sistrix()
{
return new Service\Sistrix;
}
public function Social()
{
return new Service\Social;
}
public static function getHost()
{
return self::$_host;
}
public static function getLastLoadedHtml()
{
return self::$_lastHtml;
}
public static function getLastLoadedUrl()
{
return self::$_lastLoadedUrl;
}
/**
* Ensure the URL is set, return default otherwise
* #return string
*/
public static function getUrl($url = false)
{
$url = false !== $url ? $url : self::$_url;
return $url;
}
public function setUrl($url)
{
if (false !== Helper\Url::isRfc($url)) {
self::$_url = $url;
self::$_host = Helper\Url::parseHost($url);
}
else {
throw new E('Invalid URL!');
exit();
}
return true;
}
/**
* #return DOMDocument
*/
protected static function _getDOMDocument($html) {
$doc = new \DOMDocument;
#$doc->loadHtml($html);
return $doc;
}
/**
* #return DOMXPath
*/
protected static function _getDOMXPath($doc) {
$xpath = new \DOMXPath($doc);
return $xpath;
}
/**
* #return HTML string
*/
protected static function _getPage($url) {
$url = self::getUrl($url);
if (self::getLastLoadedUrl() == $url) {
return self::getLastLoadedHtml();
}
$html = Helper\HttpRequest::sendRequest($url);
if ($html) {
self::$_lastLoadedUrl = $url;
self::_setHtml($html);
return $html;
}
else {
self::noDataDefaultValue();
}
}
protected static function _setHtml($str)
{
self::$_lastHtml = $str;
}
protected static function noDataDefaultValue()
{
return Config\DefaultSettings::DEFAULT_RETURN_NO_DATA;
}
}
and loaded the library as
$this->load->library('SEOstats');
I know this post is old. But I was looking for a solution as well recently and ended up writing my own and figured I would leave it here in case anyone else was looking for a solution in the future.
Place the following in a library file and autoload if you want.
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class SEOstatistics {
private $seostats;
function __construct() {
require_once( APPPATH . 'third_party/seostats/bootstrap.php' );
$this->seostats = new \SEOstats\SEOstats;
}
private function alexa() {
return new \SEOstats\Services\Alexa;
}
private function google() {
return new \SEOstats\Services\Google;
}
private function moz() {
return new \SEOstats\Services\Mozscape();
}
private function openSiteExplorer() {
return new \SEOstats\Services\OpenSiteExplorer();
}
private function semRush() {
return new \SEOstats\Services\SemRush();
}
private function sistrix() {
return new \SEOstats\Services\Sistrix();
}
private function social() {
return new \SEOstats\Services\Social();
}
public function __call($method, $url) {
if (method_exists($this, $method)) {
if ($this->seostats->setUrl($url[0])) {
return call_user_func_array(array($this, $method),array());
}
return false;
}
}
}
And then an example of using it in a controller or model is:
$google = $this->seostatistics->google($url);
$rank = $google->getPageRank();
This is how I include SEOStats on my Codeigniter website
class Cron extends Frontend_Controller
{
public function get_google_page_rank() {
require_once (APPPATH . 'libraries/SEOstats/bootstrap.php');
try {
$url = 'http://www.google.com/';
// Get the Google PageRank for the given URL.
$pagerank = \SEOstats\Services\Google::getPageRank($url);
echo "The current Google PageRank for {$url} is {$pagerank}." . PHP_EOL;
}
catch(\Exception $e) {
echo 'Caught SEOstatsException: ' . $e->getMessage();
}
}
public function get_alexa_page_rank() {
require_once (APPPATH . 'libraries/SEOstats/bootstrap.php');
//use \SEOstats\Services\Alexa as Alexa;
try {
$url = 'https://www.google.com/';
// Create a new SEOstats instance.
$seostats = new \SEOstats\SEOstats;
// Bind the URL to the current SEOstats instance.
if ($seostats->setUrl($url)) {
/**
* Print HTML code for the 'daily traffic trend'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(1);
/**
* Print HTML code for the 'daily pageviews (percent)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(2);
/**
* Print HTML code for the 'daily pageviews per user'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(3);
/**
* Print HTML code for the 'time on site (in minutes)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(4);
/**
* Print HTML code for the 'bounce rate (percent)'-graph.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(5);
/**
* Print HTML code for the 'search visits'-graph, using
* specific graph dimensions of 320*240 px.
*/
echo \SEOstats\Services\Alexa::getTrafficGraph(6, false, 320, 240);
}
}
catch(\Exception $e) {
echo 'Caught SEOstatsException: ' . $e->getMessage();
}
}
}
Hope this helps
PS: Copy SEOstats folder in application/libraries folder