PHP - open, read and delete data from a file - php

I have a file called functions.php.
It contains a lot of data in over 3000 lines.
Somewhere in the middle of this file there is code:
/*****************************************
My Custom Code
*****************************************/
if ( function_exists('my_code') )
my_code(array(
'name' => 'First instance',
'description' => 'Hello, hello.',
));
if ( function_exists('my_code') )
my_code(array(
'name' => 'Second instance',
'description' => 'Haha :)',
));
I'm listing all my_code arrays and I'm getting:
First Instance
Second Instance
Now, what I want to achieve, is, when user clicks X next to "First instance" PHP opens functions.php file in the background, finds the exact function and deletes it without touching anything else.
So after deleting "First Instance" functions.php file should look like this:
/*****************************************
My Custom Code
*****************************************/
if ( function_exists('my_code') )
my_code(array(
'name' => 'Second instance',
'description' => 'Haha :)',
));
Any idea how to achieve this? I know how to open files, write, delete, but I'm not sure how to wipe out not only a single line but a few lines around? :)

If your code is always in the format you described you could read each 5 lines from your file and if it's the instance you want to keep, output them to a string. Then write the string back to the original file.
But again yes, code modifying code IS PAIN. Storing your instances in a data structure such as databases or a formatted file is much better.

I think the best way would be to open the file and loop through the lines. You'll need to match each line of your function, or you would need match the first line and track the number of open and close brackets { } to know when you've reached the end of it.
If a line doesn't match you write that out to a new file. If it does match you ignore it. Then finally you make an system call to do a syntax check on the new file (in case something went wrong with your line matching):
system( "php -l newfile.php", &$retval );
Then check the return value $retval to make sure it was ok (it will be exactly equal to 0). If it is okay then you overwrite functions.php with your new file.
if( $retval === 0 ) {
// the syntax is good
rename( "newfile.php", "functions.php");
}
You would need to set the appropriate paths for this to work.
Now all of that said, this is not a very good idea and I would advise you not to implement it. A better method would be to break your functions out into separate files. Then use an INI config file or a database to keep track of what you should load. Either of those have the ability to be edited. Even a text data file would be better than mucking with the actual code.
Once you know what you're supposed to load then at the beginning require or include the appropriate file.
Here's a simple example of doing it with a database:
$res = mysql_query("SELECT file_name FROM load_functions");
if( mysql_error() ) {
// do something because the query failed
}
else {
while( list($file_name) = mysql_fetch_row($res) ) {
if( file_exists($file_name) ) {
require_once( $file_name );
}
else {
// warn because a file requested didn't exist
}
}
}
Hope that helps

Related

How to change line in config file

I have a file called settings.php that has all of the settings that the software uses. The problem is that I need users to be able to change the config without editing the file. I know I could do this with preg_replace but with dynamic settings like 'Board name' it would get tricky. I've tried a few things that didn't seem to work. I now you're not going to write the code for me, I just need a starting point.
Settings File
$settings = array (
'home_display'=>'home',
'db_host'=>'localhost',
'db_user'=>'root',
'db_password'=>'',
'db'=>'',
'login_enabled'=>true,
'signup_enabled'=>true,
'site_name'=>'Cheesecake Portal',
'b_url'=>'beta.cheesecakebb.org',
'b_email'=>'symbiote#cheesecakeb.org',
'board_enabled'=>true
);
The idea i have is to rewrite the file on the fly, even if i think this isnt the best way, it's a way.
if( file_exists($mySettingsFile) ){
include($mySettingsFile);
}
else{
$settings = array ( // the default settings array
'home_display'=>'home',
'db_host'=>'localhost',
'db_user'=>'root',
'db_password'=>'',
'db'=>'',
'login_enabled'=>true,
'signup_enabled'=>true,
'site_name'=>'Cheesecake Portal',
'b_url'=>'beta.cheesecakebb.org',
'b_email'=>'symbiote#cheesecakeb.org',
'board_enabled'=>true
);
}
// modifiy your settings here searching the key(s) you want to modify
// then put it in the config file
file_put_contents($mySettingsFile, '<?php '.var_export($settings).' ?>');
I hope this will illustrate my idea good enough to help you.

how to call a seperate php file each day of the year?

I am a beginner in PHP and would like to load a daily meditation every day that is specific to that day.
So on January 1st, I would call the quote from 1_1.php and on the 2nd 1_2.php, and so on until February 1st which would call 2_1.php and on the 2nd 2_2.php on the third 2_3.php.
Is this possible and how hard would it be?
It would also be acceptable to have 365 files where it just called the next one in order every twenty-four hours, or one file with 365 lines and called a different line every day, but I do not know how to do this as I only know how to build in html and design so any help or advice would be great.
I would most definitely not use 365 different files. It might be sensible to use a database, but since these seem to be one-liners and you are new to PHP, the simples method is to them in a big array. The downside of this is that the whole array will be read and parsed on each page load. But I wouldn't worry about the performance of that until it becomes a problem.
$meditations = array(
'1-Jan' => "Some meditation for today",
'2-Jan' => "Some meditation for tomorrow",
...
...
'28-Dec' => "Something for today",
'29-Dec' => "Something for tomorrow",
'30-Dec' => "Something for tomorrow2",
'31-Dec' => "Something for new year's eve"
);
Then access them as:
echo $meditations[date('j-M')];
// Today will output
//something for today
If you prefer, insted of using the format dd-Mon for array keys, you can use numeric months as in:
array('28-12' => "something for today");
// Access as:
echo $meditations[date('j-m')];
The complete bit to include inside your PHP page (note it will need to be a .php page, rather than .html) is:
<?php
$meditations = array(
'1-1' => "Some meditation for today",
'2-1' => "Some meditation for tomorrow",
// etc....
);
echo $meditations[date('j-m')];
?>
You can alternatively store the huge array in its own file called meditations.php, and include it:
File meditations.php
<?php
$meditations = array(
'1-1' => "Some meditation for today",
'2-1' => "Some meditation for tomorrow",
// etc....
);
?>
Main file:
<?php
include("meditations.php");
echo $meditations[date('j-m')];
?>
To include this in a plain HTML page (not .php), you'll need an <iframe>. Assuming your PHP is working correctly in a file called meditations.php, call the <iframe> like this:
<iframe src='meditations.php' />
I would use a database personally, but this is possible if you wanted to do it:
<?php
include(date("n_j").".php");
?>
The proper way to do it, is to have one PHP file which loads data from some sort of storage (most preferably database table) and each day load a record for that particular day.
If you want to stick with your multiple files you can do:
<?php
$filename = date("m")."_".date("d").".php";
if (file_exists($filename)) include($filename);
?>

Vim PHP Tab jumping to next blank line after statement

I'm having an odd problem with editing PHP files with macvim. When I press tab, instead of giving me a tab or series of spaces, it instead jumps down to a blank line after any series of statements. It will do this through the entire file until it reaches the end. For example, in the following snippet, if I have my cursor in front of "$products" and pressed tab, no tab or space would be inserted, and the cursor would land on the empty line below it:
public function index()
{
// get a distinct list of product names
$products = $this->license_model->get_all_product_names();
// get all records and fields from the view
$records = $this->license_model->get_all_records();
// assign objects to the array to pass to the view
$data = array(
'products' => $products,
'records' => $records
);
// load the view
$this->load->view('home.php', $data);
}
If I was to try and tab the comment above the $data array, the cursor would move to the line just above the next comment "load the view".
Using the vim command >> will indent the line as expected, however. The problem only seems to be with *.php files. Tabbing in say a *.java file works as normal.
Any ideas how I can fix this?
Thanks
Sounds like something has mapped <Tab> or <C-i> in insert mode to something. See what maps are defined for <Tab> by issuing:
:verbose map <Tab>
This should output any mappings that are currently set up and which file set these mappings (so you may remove them).

Best way to manage text displayed to users in PHP

Ok for sure this has been asked and answered already but i somehow can't find a proper tutorial.
I want to keep the text displayed to users somewhere else and to prevent my code from becoming too large and unreadable.
My site won't be internationalized. I just want to have some kind of file with key-value structure and get the text from there. I want to keep the text in files, not in the database as some tutorials suggest.
I found a solution which will work but i am not sure whether this is a good approach.
I am thinking of using parse_ini_file and to keep my texts in .ini file. Is there something wrong with this approach? Could you suggest something better?
I put all language data in arrays. Its easy and also we can add multi-language support
lang/en.php
<?php
return array(
'index' => 'Homepage',
'feedback' => 'Feedback'
'logout' => 'Logout from profile',
)
?>
lang/ru.php
<?php
return array(
'logout' => 'Выйти из профиля',
)
?>
Then we can load languages:
$lang = include('lang/en.php');
if(isset($_GET['lang']))
{
$lang = array_merge($lang, include('lang/ru.php'));
}
After all it $lang will look like:
Array
(
[index] => Homepage
[feedback] => Feedback
[logout] => Выйти из профиля
)
And we can very simple use it:
function __($name) {
global $lang;
return $lang[$name];
}
Somewhere in the site template:
...
<title><?=__('index')?></title>
</head>
<body>
<?=__('feedback')?>
why not use a plain text file with commas or some uncommon character to hold this data? you can read it and parse it into an array with
$file = file_get_contents("/path/to/file");
$lines = explode('\r', $file);
foreach($lines as $line) $message[substr($line, 0, strpos($line, ','))] = substr($line, strpos($line, ','));
then you should have an array like $messages[3] = "No soup for you!";
the file might look like:
1,The site is down.
2,Try again.
3,No soup for you!
4,Signs point to yes.
(I probably have some of the arguments misplaced in those functions - i always forget which is the needle and which the haystack.)
You can process your data in a script. In this script, you call a certain source (e.g. the ini file you suggest). Then you use a template engine. For this engine, you point towards a template file and give the template all the variables.
The template generates the html and inserts the variables at the right place. This way, you keep you php (business logic) code clean, away from the presentation (the template). Also you can manage the variables in one file (ini/xml but this can be something completely different).
For template engines, Smarty is the most known of all. There are also pure php-based template systems, just Google for them to find one that suits your needs.
I do like this:
$defaultLang = array('Home','Logout',etc)
$otherLang=array( 'ru' => array('Home_in_ru','logout_in_ru',etc);
you translate like this:
echo translate('Home');
function is:
function translate($msg) {
if ($_GET['lang']=='en')
return $msg;
return $otherLang[$_GET['lang']][array_search($msg,$defaultLang)];
}
// Note the function is simplified up there
As you can see the default case deosnt' need to load anything or do any operation, the function just returns back the argument passed
i like the answer with the lang/en.php file. but instead of a file for each language, i use a file for each web page (or class, etc). this keeps file sizes lower and i create a 3D array:
`return array( "EN" => array( "title" => "Welcome - Good Morning", ...),
"TG" => array( "title" => "Mabuhay - Magandang Umaga Po", ...)
);'
Real easy to add new language strings too...
This makes it real easy for language translation contractors since they can see the native language in close proximity to the foreign in 1 editor,,,

Howto: Drupal File Upload Form

I'm having difficulty figuring out how to write a module with a form that uploads files, in Drupal 6. Can anyone explain this, or point me to a good example/documentation discussing it?
EDIT:
Here is entirely what I am trying to do:
User uploads a .csv
Module reads the first line of the file to get fields
User matches csv fields with db fields
Each csv line is saved as a node (preview it first)
So far, I can do 1, 2, and 4 successfully. But it's unclear exactly how the steps should interact with each other ($form_state['redirect']? how should that be used?), and what the best practices are. And for 3, should I save that as session data?
How do I pass the file data between the various steps?
I know that node_import exists, but it's never worked for me, and my bug requests go ignored.
2nd EDIT: I used this at the start and end of every page that needed to deal with the file:
$file = unserialize($_SESSION['file']);
//alter $file object
$_SESSION['file'] = serialize(file);
I'm not sure it it's best practices, but it's been working.
This is not too difficult, you can see some info here. An example of a form with only a file upload.
function myform_form($form_state) {
$form = array('#attributes' => array('enctype' => 'multipart/form-data'));
$form['file'] = array(
'#type' => 'file',
'#title' => t('Upload video'),
'#size' => 48,
'#description' => t('Pick a video file to upload.'),
);
return $form;
}
EDIT:
Now to save the file use the file_save_upload function:
function myform_form_submit($form, $form_state) {
$validators = array();
$file = file_save_upload('file', $validators, 'path');
file_set_status($file, FILE_STATUS_PERMANENT);
}
2nd EDIT:
There's a lot of questions and ways to do the things you described. I wont go to much into the actual code of how to handle a csv file. What I would suggest is that you use the file id to keep track of the file. That would enable you to make urls that take a fid and use that to load the file you want to work on.
To get from your form to the next step, you can use the #redirect form property to get your users to the next step. From there is really depends how you do things, what you'll need to do.

Categories