I'm new to OO PHP...I'm trying to create a PHP class called MyClass and some methods that should:
validate that parameters are numeric
validate that parameters are defined
if any of the above fail I need to send an exception with explanation
When I call the MyFunction method like this:
$quotation = new Quotations\MyClass();
echo $quotationResult = $quotation -> MyFunction('A', 'B', 2, 'a');
to test if it will throw an exception but for some reason page doesn't load saying - "localhost is currently unable to handle this request". But when I call it like this:
$quotation = new Quotations\MyClass();
echo $quotationResult = $quotation -> MyFunction('A', 'B', 2, 3);
it works fine (I can see blank page).
Why it doesn't allow me to print an exception in the browser?
My script:
<?php
namespace Quotations;
class MyClass {
var $is_number;
var $is_defined;
private $number;
private $defined;
private function isNumeric($w, $c){
if(is_numeric($w) && is_numeric($c)){
$number = true;
}
else{
$number = false;
}
return $number;
}
private function isDefined($t, $f, $w, $c){
if(isset($t, $f, $w, $c)){
$defined = true;
}
else{
$defined = false;
}
return $defined;
}
function MyFunction($to, $from, $weight, $cube) {
try{
if(!$this -> isNumeric($weight, $cube)){
throw new InvalidArgumentException('Arguments are not numeric');
}
if(!$this -> isDefined($to, $from, $weight, $cube)){
throw new BadMethodCallException('Arguments are missing');
}
}catch(InvalidArgumentException $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}catch(BadMethodCallException $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
}
?>
Use backslashes before the execption names to look for them in the global namespace. Otherwise, it looks for them in the Quotations namespace.
function MyFunction($to, $from, $weight, $cube) {
try {
if(!$this -> isNumeric($weight, $cube)){
throw new \InvalidArgumentException('Arguments are not numeric');
}
if(!$this -> isDefined($to, $from, $weight, $cube)){
throw new \BadMethodCallException('Arguments are missing');
}
} catch(\InvalidArgumentException $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} catch(\BadMethodCallException $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
First step is to enable error reporting -
error_reporting(E_ALL);
ini_set("display_errors", 1);.
From looking at your code you seem to be missing a closing bracket your code should look like this.
namespace Quotations;
class MyClass {
var $is_number;
var $is_defined;
private $number;
private $defined;
private function isNumeric($w, $c) {
if(is_numeric($w) && is_numeric($c)){
$number = true;
}
else {
$number = false;
}
return $number;
}
private function isDefined($t, $f, $w, $c){
if( isset( $t, $f, $w, $c ) ){
$defined = true;
}
else {
$defined = false;
}
return $defined;
}
function MyFunction($to, $from, $weight, $cube) {
try {
if(!$this -> isNumeric($weight, $cube)){
throw new InvalidArgumentException('Arguments are not numeric');
}
if(!$this -> isDefined($to, $from, $weight, $cube)){
throw new BadMethodCallException('Arguments are missing');
}
} catch(InvalidArgumentException $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} catch(BadMethodCallException $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
}
Edit:
I saw you said in the comments you have added the } and still no luck so I looked through your code and found the following problem
So this is my last solutions I can think of xD
function MyFunction( $to, $from, $weight, $cube ) {
try
{
try
{
if( !$this->isNumeric( $weight, $cube ) ) {
throw new \InvalidArgumentException( 'Arguments are not numeric' );
}
} catch ( \InvalidArgumentException $e ) {
echo 'Error: ' . $e->getMessage();
}
try
{
if( !$this->isDefined( $to, $from, $weight, $cube ) ){
throw new \BadMethodCallException( 'Arguments are missing' );
}
} catch ( \BadMethodCallException $e ) {
echo 'Error: ' . $e->getMessage();
}
} catch ( Exception $e ) {
echo 'Error: ' . $e->getMessage();
}
}
Hope this helps
Related
So I have the following code that I built out that grabs some images from an Azure storage library:
$accountName = 'teststorageaccount';
$accountKey = '**';
$containerName = 'users';
$connectionString = "DefaultEndpointsProtocol=http;AccountName={$accountName};AccountKey={$accountKey}";
$blobClient = ServicesBuilder::getInstance()->createBlobService($connectionString);
try {
$blob_list = $blobClient->listBlobs($containerName);
$blobs = $blob_list->getBlobs();
// Grab all the blob links
foreach ($blobs as $blob) {
echo $blob->getUrl() . "</br>";
}
} catch(ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
Then I'm getting the following results back:
http://teststorageaccount.blob.core.windows.net/users/ABREUG.jpg
http://teststorageaccount.blob.core.windows.net/users/ABUKHADA.jpg
http://teststorageaccount.blob.core.windows.net/users/ACHANT.jpg
http://teststorageaccount.blob.core.windows.net/users/ACQUISTE.jpg
Now this is where I would need some help .. I'm practicing on building out everything in a class, and this is how far I've come:
class AzureStorage
{
private $accountName;
private $accountKey;
private $containerName;
public static function init()
{
return new AzureStorage([
'accountName' => 'teststorageaccount',
'accountKey' => '***',
'containerName' => 'users',
]);
}
/**************************************************************************/
public function __construct(array $data = [])
{
if (count($data) === 0) {
return;
}
$this->load($data);
}
public function load(array $data) : void
{
if (isset($data['accountName'])) {
$this->accountName = $data['accountName'];
}
if (isset($data['accountKey'])) {
$this->accountKey = $data['accountKey'];
}
if (isset($data['containerName'])) {
$this->containerName = $data['containerName'];
}
}
public function connect()
{
$connectionString = "DefaultEndpointsProtocol=https;AccountName={$this->accountName};AccountKey={$this->accountKey}";
$blobClient = ServicesBuilder::getInstance()->createBlobService($connectionString);
return $blobClient;
}
public function getContainers() : array
{
$containers = $this->connect()->listContainers();
return $containers->getContainers();
}
public function getBlobURLs()
{
try {
$blob_list = $this->connect()->listBlobs($this->containerName);
$blobs = $blob_list->getBlobs();
// Grab all the blob links
foreach ($blobs as $blob) {
echo $blob->getUrl() . "</br>";
}
} catch (ServiceException $e) {
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}
}
}
The problem: How would I be able to use the try and catch inside the getBlobURLs method and then output the results? I'm unable to get results when calling it outside the class.
Here is what I'm doing:
$test2 = new \AzureStorage\AzureStorage([
'accountName' => 'teststorageaccount',
'accountKey' => '***',
'containerName' => 'users',
]);
Now if I call the following (I get an array of containers, which works perfectly):
$containers = $test2->getContainers();
//var_dump($containers);
But if I do the following (I get no results outputted back):
$blobs = $test2->getBlobURLs();
var_dump($blobs);
Does anyone know why I might not be getting the URLs back?
You do have a return statement in getContainers function but not in getBlobURLs.
public function getBlobURLs(){
try {
$blob_list = $this->connect()->listBlobs($this->containerName);
$blobs = $blob_list->getBlobs();
$blobUrls = [];
// Grab all the blob links
foreach ($blobs as $blob) {
$blobUrls[] = $blob->getUrl();
}
return $blobUrls;
} catch (ServiceException $e) {
return false;
}
}
Now if you want to display blob url list then
$blobs = $test2->getBlobURLs();
if($blobs === false){
echo 'Error while getting blob urls.';
}
else{
foreach($blobs as $blobUrl){
echo $blobUrl . "</br>";
}
}
I want to store some products models. I'm getting these data with curl, sometimes unexpected errors happen. But I want continue to foreach loop when this happened. How can I do that ?
private function storeAllModels()
{
foreach ($this->models as $model_bundle) {
foreach ($model_bundle as $model) {
$source = $this->getSourceWithCurl($this->base_url . "/" . $model);
$details = $this->getModelDetails($source);
if ($details == "error") {
array_push($this->errors, $model);
continue;
}
try {
$model = new Product();
$model::forceCreate($details);
} catch (QueryException $e) {
array_push($this->errors, $model);
continue;
}
}
}
}
I use try catch statement but still errors break foreach loop
try with global exception class, which will catch all type of errors,
private function storeAllModels()
{
foreach ($this->models as $model_bundle) {
foreach ($model_bundle as $model) {
$source = $this->getSourceWithCurl($this->base_url . "/" . $model);
$details = $this->getModelDetails($source);
if ($details == "error") {
array_push($this->errors, $model);
continue;
}
try {
$model = new Product();
$model::forceCreate($details);
} catch (\Exception $e) {
array_push($this->errors, $model);
continue;
}
}
}
}
I've a code for command app made on laravel 5.0 with try .. catch and use system command. When there a exception, my catch not work.
use Illuminate\Support\Facades\Log;
...
try {
system('.dump master | sqlite3 ' . $older . ' > ' . storage_path() . '/tmp/' . $tabla . '.sql' );
} catch ( \Exception $e) {
Log::alert('Problem import old table '. $tabla . $e->GetMessage());
}
I see my error on shell but not write on my own laravel log. (Log:alert)
You have to gain access over STDERR and, probably, STDOUT. Use proc_open, e.g.:
$desc = [
1 => ['pipe', 'w'], // STDOUT
2 => ['pipe', 'w'], // STDERR
];
$proc = proc_open('ls -l . something', $desc, $pipes);
if (is_resource($proc)) {
if ($out = stream_get_contents($pipes[1])) {
echo $out;
}
fclose($pipes[1]);
if ($err = stream_get_contents($pipes[2])) {
fprintf(STDERR, "Error: %s\n", $err);
}
fclose($pipes[2]);
// You can also check the process exit status
// 0 means success, otherwise error.
$exit_status = proc_close($proc);
}
Of course, there is no need in STDOUT pipe, if the command redirects it to a file.
And yes, system() won't throw exceptions. Obviously, you can implement your own class which will throw an exception in case if the process exit status is non-zero, or there is something caught in the STDERR pipe:
class MyShellException extends \Exception {}
class MyShell {
public static function execute($command, &$out = null) {
if (func_num_args() > 1) {
$desc[1] = ['pipe', 'w'];
} else {
$desc[1] = ['file', '/dev/null'];
}
$desc[2] = ['pipe', 'w'];
$proc = proc_open($command, $desc, $pipes);
if (is_resource($proc)) {
if (isset($pipes[1])) {
$out = stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
if ($err = stream_get_contents($pipes[2])) {
fclose($pipes[2]);
throw new MyShellException("Command $command failed: $err");
}
if ($exit_status = proc_close($proc)) {
throw new MyShellException("Command $command exited with non-zero status");
}
}
}
}
try {
MyShell::execute('ls -l . something', $out);
echo "Output: $out\n";
} catch (MyShellException $e) {
if (!empty($out)) {
echo "Output: $out\n";
}
fprintf(STDERR, "MyShell error: " . $e->getMessage());
exit(1);
}
Use Throw Exception in php.
Here is the reference link to use and a sample example:
<?php
/*
*
* opcode number: 108
*/
try {
$error = 'Always throw this error';
throw new Exception($error);
// Code following an exception is not executed.
echo 'Never executed';
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo 'Hello World';
?>
Is there a way on including a file at the beginning of a class for all methods to use. The example below is a simplified version of what I am trying to achieve. Currently I have to include the file within every method.
Example Logic (not working)
class Myclass
{
protected require_once 'folerd1/folder2/pear/HTTP/Request2.php'; // this does not work
public function aMethod()
{
$request = new HTTP_Request2('http://example1.com/', HTTP_Request2::METHOD_GET);
try {
$response = $request->send();
if (200 == $response->getStatus()) {
echo $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
}
public function aMethod1()
{
$request = new HTTP_Request2('http://example2.com/', HTTP_Request2::METHOD_GET);
try {
$response = $request->send();
if (200 == $response->getStatus()) {
echo $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
}
// more methods
}
2 solution
1) require_once taken outside from class
require_once 'folerd1/folder2/pear/HTTP/Request2.php';
class Myclass
{
2) Include in the construct
public function __construct() {
require_once 'folerd1/folder2/pear/HTTP/Request2.php';
}
But it is better first option
The best way is to look at autoloading standard http://www.php-fig.org/psr/psr-0/
Have you tried this? I don't know what's your Request2.php file content. So my code is only a PoC!
require 'folerd1/folder2/pear/HTTP/Request2.php';
class Myclass
{
public function aMethod()
{
$request = new Request2('http://example1.com/', Request2::METHOD_GET);
try {
$response = $request->send();
if (200 == $response->getStatus()) {
echo $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
}
public function aMethod1()
{
$request = new Request2('http://example2.com/', Request2::METHOD_GET);
try {
$response = $request->send();
if (200 == $response->getStatus()) {
echo $response->getBody();
} else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
} catch (Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
}
}
As I commented out, just require the file in the constructor of the PHP class:
class Myclass{
function Myclass(){
require_once('folerd1/folder2/pear/HTTP/Request2.php');
}
I have not checked this, but it MIGHT be possible that what you're just doing is including it not only for all the class to see, but the entire script. Please, check that out if it is a problem for you. If not, the other 2 solutions might end up doing the same.
Cheers
How to catch an error from a SOAP?
How can I avoid the fatal error and convert it to my own error.. In this example it's a SERVER_BUSY
code
class Validate_vatno {
private $client = null;
private $options = array(
'debug' => false
);
public function __construct(){
$this->client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', array('trace' => true));
}
public function check($country, $vatno){
$result = $this->client->checkVat(array(
'countryCode' => $country,
'vatNumber' => $vatno
));
if(!empty($this->options['debug'])){
echo '<pre>'.htmlentities($this->client->__getLastResponse()).'</pre>';
}
if($result->valid){
list($denomination, $name) = explode(' ', $result->name, 2);
return array(
'denomination' => utf8_decode($denomination),
'name' => ucwords(utf8_decode($name)),
'address' => ucwords(utf8_decode($result->address)),
);
}
else{
return array();
}
}
}
$vatValidation = new Validate_vatno();
if($return = $vatValidation->check('DK', 33214944)){
echo '<h1>valid one!</h1>';
echo 'denomination: ' . $return['denomination']. '<br/>';
echo 'name: ' . $return['name']. '<br/>';
echo 'address: ' . $return['address']. '<br/>';
}
else{
echo '<h1>Invalid VAT</h1>';
}
error
Fatal error: Uncaught SoapFault exception: [soapenv:Server] { 'SERVER_BUSY' } in /var/www/
Review how to handle exceptions
Throwing and Catching a Exception
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
else return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo 'Hello World';
?>