Sorry everyone, I'm kind of new to AWS SDK but I need to use WriteRequestBatch to add bulks of 25 records to one table.
I'm using Codeigniter and trying to do it with this code:
function new_save($data_set)
{
$tableName = 'my-table';
$dynamodb = $this->aws_sdk->dynamo_db();
$data_to_save = $this->create_dynamo_data($data_set);
$putBatch = WriteRequestBatch::factory($dynamodb);
foreach ($data_to_save as $record)
{
$record = Item::fromArray($item);
$putBatch->add(new PutRequest($record, $tableName));
}
$putBatch->flush();
}
but it stops with this error:
PHP Fatal error: Class 'WriteRequestBatch' not found in (...)
I've just started to use new SDK and I am able to get data and update table throughput settings etc, only this task fails on me totally :-(
BTW - this is my first post here, and I tried to search on Google etc for answers but found only the same sample code I use already.
I created a library like this:
require('/var/www/xx-aslan/aws_sdk_ver2/aws-autoloader.php');
use Aws\Common\Aws;
class Aws_sdk
{
// Create a service locator using a configuration file
private static $aws = array(
'key' => '***********',
'secret' => '******',
'region' => '****'
);
function aws()
{
return Aws::factory(self::$aws);
}
function dynamo_db()
{
$aws = $this->aws();
return $aws->get('DynamoDb');
}
and I am loading it in the model where the function new_save() is:
$this->load->library('aws_sdk');
Anyone could help me out here?
I know it's probably some really newbie question, sorry :-(
Thanks in advance!
Kasia
If it does not work to change:
$this->load->library('aws_sdk');
to
$this->load->library('Aws_sdk');
as I suggested in the comments, try calling it like:
$putBatch = aws_sdk->WriteRequestBatch::factory($dynamodb);
You would do this every time you use your aws_sdk library.
Hope this helps.
This is not a problem with the AWS SDK or with CI. The classes are namespaced, so you must import them to make them available.
In the same file that you are referencing them, add use statements at/near the top of the file (outside of any class or function declarations).
<?php
// ...
use Aws\DynamoDb\Model\BatchRequest\PutRequest;
use Aws\DynamoDb\Model\BatchRequest\WriteRequestBatch;
use Aws\DynamoDb\Model\Item;
// ...
function new_save($data_set)
{
// ...
$putBatch = WriteRequestBatch::factory($dynamodb);
// ...
}
// ...
You should consider giving the namespaces section in the PHP manual a read if you want to get a better understanding of how to work with namespaced code.
Related
I'm not very experienced with php projects structure, I found this awesome and simple tutorial: https://arjunphp.com/creating-restful-api-slim-framework/ how to create simple slim rest app.
This is actually PHP SLIM's official project structure, my question is what is best and proper way to add and use RedBean php ORM, I dont want on every route to include something like this
use \RedBeanPHP\R as R;
R::setup( 'mysql:host=localhost;dbname=mydatabase', 'myusername', 'mypassword)
and then
$book = R::load( 'book', $id );
And then use ReadBean for my db stuff. Im wondering how to include RedBeans into project and then just use it where i need it. This is my project structure https://github.com/iarjunphp/creating-restful-api-slim-framework3.
Note: i added red beans via composer like its described here https://github.com/gabordemooij/redbean
You can put the code for setting up your libraries in any file that is going to be included on each request, so assuming you're using slim/slim-skeleton, src/dependencies.php is probably the place you want to add these two lines:
use \RedBeanPHP\R as R;
R::setup( 'mysql:host=localhost;dbname=njux_db', 'root', '');
Then you can use ReadBeans in your route callbacks but you also need to add the use \RedBeanPHP\R as R; statement to your src/routes.php as well (or any file that is going to use this class)
If you use a MVC framework (which I recommend) like codeigniter it's pretty easy.
You only have to copy your rb.php to the application/third_party folder.
Then create a file called application/libraries/rb.php containing a code like this one.
<?php
class Rb {
function __construct() {
include(APPPATH.'/config/database.php');
include(APPPATH.'/third_party/rb.php');
$host = $db[$active_group]['hostname'];
$user = $db[$active_group]['username'];
$pass = $db[$active_group]['password'];
$db = $db[$active_group]['database'];
R::setup("mysql:host=$host;dbname=$db", $user, $pass);
}
}
?>
...and vĂ´ila. RedBean will read your database configuration from CodeIgniter's standard file application/config/database.php and you will be able to use any R:: command from anywhere in your code. No includes, not additional code required :-)
My journey into Laravel 4 continues. I'm trying to develop a menu that is dynamically created on the master view. To do this I found this article, and I'm trying to implement it.
I've got the code so far but this part appears to be causing a problem:
App::before(function ($request) {
// $myApp Singleton object
App::singleton('myApp', function () {
$app = new stdClass;
$app->title = "downsCMS";
if (Sentry::check()) {
$app->user = Sentry::getUser();
$app->isLogedin = TRUE;
} else {
$app->isLogedin = FALSE;
$app->user = FALSE;
}
return $app;
});
$app = App::make('myApp');
View::share('myApp', $app);
});
WHen I try to run the app I get a class not found 'myApp'
So it appears it's not creating the class. I did a composer dump-autoload but no effect.
I must admit I don't fully understand the ioc so please be gentle. Are there simple steps I am missing here?
Try unwrapping the block of code from within App::before(). Temporarily place the block of code at the top of the routes.php file and see what happens. If this fixes the issue, look into wrapping your code in a "service provider" class. That way it won't "muck up" the routes file, and will be tucked away nicely.
I gave up trying to implement the code - I re-wrote without creating a singleton.
It may not be as efficient but it works for now
Ta
I am having that error , whenever I ran my simple cron script in shell ,
any idea how to fix that thing ?, from the error itself, it says the .user is undefiend,
when I placed the
'user' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
'loginUrl' => array('myaccount/blah/login'),
in the console config, it is looking for a "Class" ,, what class am i supposed to include in that array? , this user login url is using an LDAP stuff in loggin in and authentication, what should I do ?
A CConsoleApplication is for handling offline tasks. For example, the application starts a cronjob within a linux system. The application checks each day if a registered user of your website should change his password, because it must be changed every 3 month. If the password expired send an email.
To preselecting the users you have set a scope condition to check the status of a user, as well as a scope to restricted signed in users on her own data:
public function scopes(){
return array(...,
'user' => array(
'condition'=>'id='.Yii::app()->user->id,
),
'active' => array(
'condition'=>'status='.self::STATUS_ACTIVE,
), ...
);
}
Now, in your CCA-Code you use the active scope to get all users:
$usersArray = User::model()->active()->findAll(); ...foreach.... The Problem here is in the use of the extended class, the CActiveRecord-class. Mostly used as a class extension in models, which are stored in a database. In this CActiveRecord-class the CActiveRecord->__call function is used to get all stored scopes of a model. After that the class merged the actually requested scopes with the rest of the database criteria. The fact that all scopes are loaded first occures the error in loading the user-scope, include Yii::app()->user->id. The WebUser is called and throws the exception 'CException' with message 'attribute "CConsoleApplication.user is not defined'. You wouldn't call the WebUser, but the automatism arrange this for you :-)
So, do it like schmunk says. Generate in your scope code an exception part where ensures that Yii::app()->user is not called:
public function scopes(){
if (Yii::app() instanceof CConsoleApplication) {
$user = array(''); //no condition
}else{
$user = array(
'condition'=>'id='.Yii::app()->user->id,
);
}
return array(
'user' => $user,
'active' => array(
'condition'=>'status='.self::STATUS_ACTIVE,
), ...
);
}
I hope the explanation helps and perhaps also for other problems.
Short answer: You can't use CWebUser in console application. Don't include it in your config/console.php
Long(er) answer: If you rely on a component, which needs CWebUser, you'll have to detect this in the component and create some kind of workaround for this case. Have a look at this code piece for an example how to detect, if you're running a console app.
Try this
public static $console_user_id;
public function init() {
if (Yii::app() instanceof CConsoleApplication) {
if (self::$console_user_id) $this->id = self::$console_user_id;
return false;
}
parent::init();
}
solved my problem by using update, instead of save in the script...no need to use user array and CWebUser class
I had the same problem. Screened all answers given here and found some good point, but solved my problem my way, although it may not be the best.
First off all I had to figure out that my Cron Jon threw the aforementioned Exception because inside the Cron job I was running a script which had this part of code in it
if(Yii::app()->user->isAdmin()) {...} else {...}
So the console threw the error since the user was not defined. I changed my code in such a way that I tested if the console was running it. The changed code is as follows:
$console = false;
try {
$test = Yii::app()->user->isAdmin();
}
catch (CException $e) {
$console = true;
}
if($console || (!$console && Yii::app()->user->isAdmin()) {...} else {...}
As said, not perfect, but maybe a solution for someone.
I'm experiencing a problem with my SOAP solution. Sometimes I get an error saying the following:
Function (functionA) is not a valid method for this service
Edit 8 months later
Although I could not find the cause of the problem I was able to work around it. Whenever I recieve an response from the API I check for the SoapFault and just send another identical request and use the answer that comes back the second time.(posted as an answer)
This occurs in calls from PHP like:
functionA() - expected response
functionA() - expected response
functionA() - SoapFault
functionA() - expected response
Same result is to be expected in all the above calls and the same parameters are used(if any). Since it's working fine for almost all calls I know that the function and the corresponding WSDL is there.
What I thougt were the problem was caching an old version which would not have that function. I tried disabling the caching with:
ini_set("soap.wsdl_cache_enabled", "0");
And makeing every call with added with a random dummy parameter as well as disabling it when I use Zend_SoapClient.
'cache_wsdl' = false
I hope someone could point me in any direction or have any direct suggestion on what could be the cause.
My code looks like:
public function __construct()
{
$wsdl = "http://catlovers.nl/index.php?wsdl&dummy=".rand(1000,9999);
$this->_client = new Zend_Soap_Client($wsdl, array(
'soapVersion' => SOAP_1_1,
'cache_wsdl' => false
));
$this->_client->setWsdlCache(false);
}
function __call($name, $arguments) // Calls are made this way
{
array_unshift($arguments, $this->_apiKey, $this->_user, $this->_password);
return call_user_func_array(array($this->_client, $name), $arguments);
}
public function getCat()
{
return ($this->__call('getCat',array()));
}
On "the other side" I have:
$server = new nusoap_server();
$server->wsdl->addComplexType('Cat', ....
$server->register( 'getCat', return Cat ...
function getCat($apikey, $email, $password)
{
$cat = $db->get("redCat");
return $cat;
}
First of all, try to call function using built-in SoapClient class and printing debug information:
$wsdl = "http://abcd.com/index.php?wsdl&dummy=".rand(1000,9999);
$soap = new SoapClient($wsdl, array(
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => true,
));
try {
var_dump($soap->functionA());
} catch ( Exception $ex ) {
var_dump($ex);
}
var_dump($soap->__getLastRequest());
var_dump($soap->__getLastRequestHeaders());
var_dump($soap->__getLastResponse());
var_dump($soap->__getLastResponseHeaders());
This way you'll know where is the problem. If everything is ok all the time, the problem is in Zend's class. If not, look what service responds. May be there is some server-side error or dummy generation with such id fails
I guess your problem is related to nusoap, because for many years I'm using PHP soap server/client and I never faced this problem. (but I always had strange problems with nusoap lib)
currently I'm using jool.nl web service helper which is very powerfull yet neat and object oriented library not only makes coding easier and cleaner but also provides you object oriented approach to web service designing. It also provides a nice web interface for your web service with documentation.
As this library uses internal PHP SOAP server I'm pretty sure you're problem will be disappear then.
I suggest you to give it a try and I'm sure if you make your first web service with this library you will never try something else.
I hope this helps you.
So the problem was still there after trying other solutions so I was never able to find underlying cause of the problem. On the other hand I found a way to work around the problem that has been working since I wrote it. This is how my call to the API looks like with user,password and key for authentication.
function __call($name, $arguments)
{
/* Using the stored data to ensure that the user is allowed to access */
/* ............... */
array_unshift($arguments, $this->_apiKey, $this->_user, $this->_password);
$call = call_user_func_array(array($this->_client, $name), $arguments);
if(isset($call->faultstring) && substr(trim($call->faultstring),0,7) == "Function")
{
$recall = call_user_func_array(array($this->_client, $name), $arguments);
return $recall;
}
else
return $call;
}
This is basicly: if it doesn't work the first time just try again.
I have been using predis to try to figure out how to run raw redis commands, but I am having trouble. The documentation for predis is extremely outdated. It says that there is a method called "rawCommand()" which will allow a user to run raw Redis commands, but I found a changelog that says it is no longer supported:
https://github.com/nrk/predis/blame/master/CHANGELOG
Does anyone have any hints of how I can run raw redis commands?
Here you go. This has worked perfectly for me, and I did not know it even had that function
$cmdSet = $redis->createCommand('set');
$cmdSet->setArgumentsArray(array('library', 'predis'));
$cmdSetReply = $redis->executeCommand($cmdSet);
He has a wiki page on this. Look for sending commands.
I'm actually guessing here, but let's pretend for a while I did not say that aloud.
Check out the function writeCommand() in lib/Predis/Network/StreamConnection.php on line 176 and use it through SimpleDebuggableConnection in examples/SimpleDebuggableConnection.php. You still have to define new commands that are not already defined in lib/predis/commands, as mentioned in the wiki that #Colum referred to.
If you're really feeling adventurous, change the protected method writeBytes() in StreamConnection on line 96 to public. That should enable you to feed it pure redis with
$redis->getConnection()->writeBytes("*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n")
Unfortunately, publicizing the writeBytes() seems to go in to the direction of http://en.wikipedia.org/wiki/Object_orgy anti-pattern.
Good luck!
It's easy!
Take this class: RedisServer
and write:
$redis = new \Jamm\Memory\RedisServer();
$redis->send_command('set','key',5); //here any raw command
PHPRedis
on phpredis extension you can use following:
$redis->rawCommand("count", "a:", 10, "a:");
PRedis
on phpredis you can use following:
$redis->executeRaw(["count", "a:", 10, "a:"]);
PRedis - more complicated way
on predis you can do like this:
<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
class PRredisCOUNT extends Predis\Command\Command {
function getId(){
return 'COUNT';
}
}
class PRredisSUM extends Predis\Command\Command {
function getId(){
return 'SUM';
}
}
function registerHM4Commands($redis){
$redis->getProfile()->defineCommand("count" , "PRredisCOUNT" );
$redis->getProfile()->defineCommand("sum" , "PRredisSUM" );
}
$redis = new Predis\Client("127.0.0.1:2000");
registerHM4Commands($redis);
// after that you can do:
$redis->count($key, $page, $prefix);